Click here to Skip to main content
Click here to Skip to main content

Server Client Sockets

By , 25 Apr 2003
 

Introduction

The reason why I decided to write this article is because, I was learning myself how to use sockets with under windows, I could not find one place that had a tutorial which included every thing i was looking for, or if it did it was way to complicated for me to understand. In the end after doing my research I put together my resources and came up with this tutorial. I hope that it is clear and informative so that other people can benefit from it

This article be divided into 3 section:

  • part 1 - Create a server socket that listen for a client to connect
  • part 2 - send / receive data from client to server
  • part 3 - Read unknow size of data from client

Part 1 - Creating a listening socket

To use WinSock before we start writing any code we must include the wsock32.lib and include the

#pragma comment(lib, "wsock32.lib")

Normally a socket that waits for a connection is a server, Once the connection has been made it can spawn off a new Thread to deal with that connection.

Before going into the acual code lets have a look some struct we will need to set up a socket:

WSDATA:

Any code that is compiled using a winsock accesses the ws2_32.dll and this struct is used during the process of doing so. The program MUST call WSAstartup to initialise the DLL for later use

SOCKADDR_IN:

This is used to specify how the socket is used and contains the field for the IP and port

SOCKET:

This is an object that stores a handle to the socket

Key functions to create the listening server socket

WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData )

This function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets API required and to retrieve details of the specific Windows Sockets implementation. The application or DLL may only issue further Windows Sockets API functions after a successful WSAStartup invocation.

socket(int af, int type, int protocol)

This method creates the socket

bind(SOCKET s, const struct sockaddr FAR * name, int namelen)

Associates a local address with a socket This routine is used on an unconnected datagram or stream socket, before subsequent connects or listens. When a socket is created with socket, it exists in a name space (address family), but it has no name assigned. bind establishes the local association (host address/port number) of the socket by assigning a local name to an unnamed socket. In the Internet address family, a name consists of several components. For SOCK_DGRAM and SOCK_STREAM, the name consists of three parts: a host address, the protocol number (set implicitly to UDP or TCP, respectively), and a port number which identifies the application. If an application does not care what address is assigned to it, it may specify an Internet address equal to INADDR_ANY, a port equal to 0, or both. If the Internet address is equal to INADDR_ANY, any appropriate network interface will be used; this simplifies application programming in the presence of multi- homed hosts. If the port is specified as 0, the Windows Sockets implementation will assign a unique port to the application with a value between 1024 and 5000. The application may use getsockname after bind to learn the address that has been assigned to it, but note that getsockname will not necessarily fill in the Internet address until the socket is connected, since several Internet addresses may be valid if the host is multi-homed. If no error occurs, bind returns 0. Otherwise, it returns SOCKET_ERROR, and a specific error code may be retrieved by calling WSAGetLastError.

listen(SOCKET s, int backlog )

Establishes a socket to listen to a incoming connection To accept connections, a socket is first created with socket, a backlog for incoming connections is specified with listen, and then the connections are accepted with accept. listen applies only to sockets that support connections, i.e. those of type SOCK_STREAM. The socket s is put into "passive'' mode where incoming connections are acknowledged and queued pending acceptance by the process. This function is typically used by servers that could have more than one connection request at a time: if a connection request arrives with the queue full, the client will receive an error with an indication of WSAECONNREFUSED. listen attempts to continue to function rationally when there are no available descriptors. It will accept connections until the queue is emptied. If descriptors become available, a later call to listen or accept will re-fill the queue to the current or most recent "backlog'', if possible, and resume listening for incoming connections.

accept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen)

This routine extracts the first connection on the queue of pending connections on s, creates a new socket with the same properties as s and returns a handle to the new socket. If no pending connections are present on the queue, and the socket is not marked as non- blocking, accept blocks the caller until a connection is present. If the socket is marked non-blocking and no pending connections are present on the queue, accept returns an error as described below. The accepted socket may not be used to accept more connections. The original socket remains open. The argument addr is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr; on return it will contain the actual length (in bytes) of the address returned. This call is used with connection-based socket types such as SOCK_STREAM. If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.

closesocket(SOCKET s)

closes a socket

WSACleanup()

Ends the use of the Windows Sockets DLL.

Example program

#include <stdio.h>
#include <winsock.h>
#include <windows.h>

#define SERVER_SOCKET_ERROR 1
#define SOCKET_OK 0

#pragma comment(lib, "wsock32.lib")

void socketError(char*);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, 
                    LPSTR lpCmdLine, int nShow)
{
    WORD sockVersion;
    WSADATA wsaData;
    int rVal;

    sockVersion = MAKEWORD(1,1);
    //start dll
    WSAStartup(sockVersion, &wsaData);

    //create socket
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(s == INVALID_SOCKET)
    {
        socketError("Failed socket()");
        WSACleanup();
        return SERVER_SOCKET_ERROR;
    }

    //fill in sockaddr_in struct 

    SOCKADDR_IN sin;
    sin.sin_family = PF_INET;
    sin.sin_port = htons(8888);
    sin.sin_addr.s_addr = INADDR_ANY;

    //bind the socket
    rVal = bind(s, (LPSOCKADDR)&sin, sizeof(sin));
    if(rVal == SOCKET_ERROR)
    {
        socketError("Failed bind()");
        WSACleanup();
        return SERVER_SOCKET_ERROR;
    }

    //get socket to listen 
    rVal = listen(s, 2);
    if(rVal == SOCKET_ERROR)
    {
        socketError("Failed listen()");
        WSACleanup();
        return SERVER_SOCKET_ERROR;
    }

    //wait for a client
    SOCKET client;

    client = accept(s, NULL, NULL);

    if(client == INVALID_SOCKET)
    {
        socketError("Failed accept()");
        WSACleanup();
        return SERVER_SOCKET_ERROR;
    }

    //close process
    closesocket(client);
    closesocket(s);

    WSACleanup();

    return SOCKET_OK;
};

void socketError(char* str)
{
    MessageBox(NULL, str, "SOCKET ERROR", MB_OK);
};

Making client connection with server

In order to create a socket that connects to an other socket uses most of the functions from the previous code with the exception of a struct called HOSTENT

HOSTENT:

This struct is used to tell the socket to which computer and port to connect to. These struct can appear as LPHOSTENT, but it actually means that they are pointer to HOSTENT.

Client key function

Most of the functions that have been used for the client to connect to the server are the same as the server with the exception of a few. I will just go through the different functions that have been used for the client.

gethostbyname(const char* FAR name)

gethostbyname returns a pointer to a hostent structure as described under gethostbyaddr. The contents of this structure correspond to the hostname name. The pointer which is returned points to a structure which is allocated by the Windows Sockets implementation. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls. A gethostbyname implementation must not resolve IP address strings passed to it. Such a request should be treated exactly as if an unknown host name were passed. An application with an IP address string to resolve should use inet_addr to convert the string to an IP address, then gethostbyaddr to obtain the hostent structure.

example code

#include <windows.h>
#include <winsock.h>

#pragma comment(lib, "wsock32.lib")

#define CS_ERROR 1
#define CS_OK 0

void sError(char*);

int WINAPI WinMain(HINSTANCE hHinst, HINSTANCE hPrevHinst, LPSTR lpCmdLine, 
                   int nShow)
{

    WORD version;
    WSADATA wsaData;
    int rVal=0;

    version = MAKEWORD(1,1);

    WSAStartup(version,(LPWSADATA)&wsaData);

    LPHOSTENT hostEntry;

    //store information about the server
    hostEntry = gethostbyname("hibbert");

    if(!hostEntry)
    {
        sError("Failed gethostbyname()");
        //WSACleanup();
        return CS_ERROR;
    }

    //create the socket
    SOCKET theSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(theSocket == SOCKET_ERROR)
    {
        sError("Failed socket()");
        return CS_ERROR;
    }

    //Fill in the sockaddr_in struct
    SOCKADDR_IN serverInfo;

    serverInfo.sin_family = PF_INET;
    serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);

    serverInfo.sin_port = htons(8888);

    rVal=connect(theSocket,(LPSOCKADDR)&serverInfo, sizeof(serverInfo));
    if(rVal==SOCKET_ERROR)
    {
        sError("Failed connect()");
        return CS_ERROR;
    }

    closesocket(theSocket);
    WSACleanup();
    MessageBox(NULL, "Connection was made", "SOCKET", MB_OK);
    return CS_OK;
}

void sError(char *str)
{
    MessageBox(NULL, str, "SOCKET ERROR", MB_OK);
    WSACleanup();
}

Part 2 - Send / recieve

Up to this point we have managed to connect with our client to the server. Clearly this is not going to be enough in a real-life application. In this section we are going to look into more details how to use the send/recv functions in order to get some communication going between the two applications.

Factually this is not going to be difficult because most of the hard work has been done setting up the server and the client app. before going into the code we are going to look into more details the two functions

send(SOCKET s, const char FAR * buf, int len, int flags)

send is used on connected datagram or stream sockets and is used to write outgoing data on a socket. For datagram sockets, care must be taken not to exceed the maximum IP packet size of the underlying subnets, which is given by the iMaxUdpDg element in the WSAData structure returned by WSAStartup. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

recv(SOCKET s, const char FAR * buf, int len, int flags)

For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer supplied is returned. If the socket has been configured for in- line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application may use the ioctlsocket SIOCATMARK to determine whether any more out-of-band data remains to be read.

Code Example

The following code example demonstrates how to make use of the recv function. The recv function is used after the accept function, and the socket must be connected in order to receive the data.

    client = accept(s, NULL, NULL);

    cout << "newclient found" << endl;

    if(client == INVALID_SOCKET)
    {
        socketError("Failed accept()");
        WSACleanup();
        return SERVER_SOCKET_ERROR;
    }

    char buf[4]; 
    rVal = recv(client, buf, 4, 0);

    if(rVal == SOCKET_ERROR)
    {
        int val = WSAGetLastError();
        if(val == WSAENOTCONN)
        {
            cout << "socket not connected" << endl;
        }
        else if(val == WSAESHUTDOWN )
        {
            cout << "socket has been shut down!" << endl;
        }
        socketError("Failed recv()");
        return SERVER_SOCKET_ERROR;
    }

    cout << buf << endl;

This code example below works fine when you know exactly how much data you are about to receive. The problem comes when you do not know how much data will arrive. For now we will ignore this problem because the aim here is actually prove that data has been received. In the next section we will evolve the way we receive data.

Now we are going to look at how to implement the send function. In Actual fact it is the reverse of receiving data!

    rVal=connect(theSocket,(LPSOCKADDR)&serverInfo, sizeof(serverInfo));

    if(rVal==SOCKET_ERROR)
    {
        sError("Failed connect()");
        return CS_ERROR;
    }

    char *buf = "data";

    rVal = send(theSocket, buf, strlen(buf), 0);

    if(rVal == SOCKET_ERROR)
    {
        sError("Failed send()");
        return CS_ERROR;
    }

part 3 - Read unknow size of data from client

Us mentioned earlier in part 2, we are noe going to expand on the way that we receive data. The problem we had before is that if we did not know the size of data that we where expecting, then the would end up with problems.

In order to fix this here we create a new function that receive a pointer to the client socket, and then read a char at the time, placing each char into a vector until we find the '\n' character that signifies the end of the message.

This solution is clearly not a robust or industrial way the read data from one socket to an other, because but its a way to start reading unknown length strings. the function will be called after the accept method

char * readline(SOCKET *client)
{
    vector<char> theVector;
    char buffer;
    int rVal;

    while(true)
    {
        rVal = recv(*(client), &buffer, 1, 0);
        if(rVal == SOCKET_ERROR)
        {
            int errorVal = WSAGetLastError();

            if(errorVal == WSAENOTCONN)
            {
                socketError("Socket not connected!");
            }
            socketError("Failed recv()");
            WSACleanup();
        }
        
        if(buffer == '\n')
        {
            char *data = new char[theVector.size() + 1];
            memset(data, 0, theVector.size()+1);
            
            for(int i=0; i<theVector.size(); i+=1)
            {
                data[i] = theVector[i];
            }

            cout << data << endl;
            return data;
        }
        else
        {
            theVector.push_back(buffer);
        }
    }
}

As we can see this is simple and rudimentary way to read a line, we can increase its functionality adding support for \b, \r, \0, and others depending on what the need is.

Conclusion

I hope this tutorial has been of some use, even if the code implementation is fairly simple it might be of help to further develop programs that need to implement the socket API.

There are many more things to consider when developing with sockets, i.e. NON-Blocking and Asynchronous Socket. I intend to write some more regarding the obove topics mentioned as they are very important for more robust and industrial programs

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Emiliano
Web Developer
United Kingdom United Kingdom
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalsending image synchronizingly Pinmembermavsolos14-Apr-07 10:48 
hi,
I took the image from the web camera as frame and convert the raw image to
the jpeg file by using OpenCV program which is the C library.Later I read the image and send it from client to server with stream sockets.But I want to send the image synchronizingly as soon as takng from web camera.I think I don't need to save the frame as a file.How can I achieve this.I wil be so happy if you help me. I can also send the code as well.

Generalsending bitmap file using this code Pinmembermavsolos15-Feb-07 1:37 
hi,all.I want to send bitmap file that was written in VC++ using this code.This code works well.The message can be sent from client to server.But How can I send the bitmap file.Thanks
GeneralRe: sending bitmap file using this code Pinmemberjohn_17269-May-07 16:24 
Send the data as a BYTE type. Emiliano's program only works with textual characters.
GeneralRe: eror part Pinmember_KD_23-Jan-07 5:52 
GeneralFailed gethostbyname() Pinmemberashwag1-Nov-06 8:01 
hi Emiliano
i try to run your Server Client Sockets when i compile it i have this error
Failed gethostbyname()
 
can u help me with this.. i used vc++.net
thx
ashwag
GeneralRe: Failed gethostbyname() Pinmemberjohn_17269-May-07 16:21 
Generalproblems on Vc6 Pinmemberraggnar23-Sep-06 15:37 
hi Emiliano
i try to run your Server Client Sockets when i compile it i have no error but as soon as i try to execute i have this error
 
--------------------Configuration: server - Win32 Debug--------------------
Linking...
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/server.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
 
server.exe - 2 error(s), 0 warning(s)
 
Basically what i did i just copy the first example in your test compile then execute it. Am i doing something wrong ?
GeneralRe: problems on Vc6 Pinmemberarasn27-Oct-06 9:25 
GeneralVisual C++ Express edition Pinmemberdarida_400015-Aug-06 3:24 
Hi Emiliano, I was trying to use your code in Visual c++ Express, but it gives me tons of errors.
I was wondering: does VC++ EE support this (paricularry regarding winsock stuff)?
How do I write a skeleton TCP/IP server client APP in Visual C++ EE ?
Thanks
dario
GeneralRe: Visual C++ Express edition Pinmemberpsalm3_33-May-07 10:22 
QuestionI have a compile problem PinmemberRay H. M24-Jul-06 13:54 
When I compile the file, Server_part1 thru part_3 and client_part 1 and 2, I get 2 errors.
 
I compiled with Visual Studio 6.0 C++. Does anyone have the same problem?
 
I have all the library files too.

AnswerRe: I have a compile problem Pinmemberjohn_17269-May-07 16:26 
Generalit's a good example Pinmemberytfrdfiw14-May-06 15:11 
this is article about winsocket programming is good.the thinking of introducing is very clear.
 
ytfrdfiw
Generalhi, pls teach me PinmemberPetiao10-Jan-06 21:29 
i now already can connect client to server by using socket, now i want to using client side keyboard and mouse to replace the server keyboard and mouse, how can i make it? thank you
 
nick
Generalhi, pls teach me PinmemberPetiao11-Jan-06 17:07 
GeneralSSL sockets Pinmembercharlie1008-Sep-05 18:33 
Hello, your article is perfect!
I am looking for some SSL sockets example for Windows XP & Windows CE, can you direct some?
Thanks.
Charlie Confused | :confused:

GeneralRe: SSL sockets PinmemberTomice15-Aug-06 4:01 
GeneralComplex structure of incoming data PinsussLucke25-May-05 16:48 
I have a class CMessage
class CMessage
{
CString s1;
CString s2;
CMyClass sc;//Including CList pointer, CString and other structure
///Some function;
};
CMessage Msg;// already called some functions
How can i send and receive this Msg in both Client/server?
Please help me!!
GeneralRe: Complex structure of incoming data Pinmemberjobe377431-May-05 3:06 
GeneralVery good link! PinmemberPriyank Bolia16-Apr-05 18:25 
http://www.csc.vill.edu/~mdamian/Sockets/TcpSockets.htm
 
http://www.priyank.in/
GeneralRe: Very good link! PinmemberPeer057427-Oct-07 3:47 
Generalvc++.net Pinmemberchal_adiera7-Mar-05 22:49 
hi...
 
thanks for your article n sample...
that help me more to develop socket programming..
 
i'm a beginner in vc++.net.
can u give a sample server client sockets in vc++.net.
i try to convert you code in vc++.net but the syntax is totally different.
 
plz guide me in this problem..
tq..
 

 

 
salwa
GeneralRe: vc++.net PinmemberEmiliano18-Mar-05 0:27 
GeneralRe: vc++.net Pinmemberchal_adiera20-Mar-05 17:02 
GeneralRe: vc++.net PinsussEmiliano20-Mar-05 23:45 
GeneralRe: vc++.net Pinmemberchal_adiera21-Mar-05 15:07 
GeneralRe: vc++.net PinmemberEmiliano25-Mar-05 3:28 
GeneralNon-Blocking sockets PinsussElectrovik7-Dec-04 10:01 
I just want to know how you tell a socket to be non-blocking?
 
I tried "ioctlsocket" with FIONBIO and a non-zero long value and it didn't work.
 
Can you post a sample?
 
I also want to know how to reuse a connection. My app works fine the first time, but when I try another time, without stopping the execution, the bind() call returns a 10048 error. I delete my WSADATA and my SOCKET objects at the end of the first pass. I don't delete my SOCKADDR_IN object though...
 
Thank you!
Generalh Pinmembersyaks25-Nov-04 7:46 
i am a beginer to socket programming, i read your article i think it the best for beginers like me,
my question is i want the application to act as server and client simultaneously, and can chat with multiple peers simultaneously. what should i do to make the application work in the above mentioned way,
thanks and bye.
 

 
ShehrYar.
GeneralRe: h PinmemberEmiliano28-Nov-04 22:37 
GeneralRe:how to make one application work as a server and client simultaneously Pinmembersyaks29-Nov-04 8:22 
Questiondos 16 bit version? Pinmemberporac6916-Oct-04 13:56 
hey there,
 
Is there any way i can alter your .cpp files and/or .h files to be able to be used in a 16 bit (dos)
project?
 
what my end goal is, is to control devices over the internet...in other words, instead of sending text messages to one another, i must send commands from the client (like INPORTB,...) and i must receive status of the devices (like OUTPORTB,...).
 
I can only use this kind of mode (dos 16 bit) because the microchip i am trying to control remotely connected to the server only supports borland 5.02 DOS 16 BIT projects.
 
thank you for helping and any suggestions are heart-warmingly welcome!
porac69


GeneralTom Cruise Pinmembert2di4u28-Sep-04 21:45 
The pose looks like the poster of mission impossible.
GeneralRe: Tom Cruise PinmemberEmiliano29-Sep-04 5:00 
GeneralSure Pinmembert2di4u30-Sep-04 6:22 
GeneralSETTING UP NUMERICAL IP ADDRESS Pinmemberdikads13-Jul-04 1:25 
hello, im new in socket programming andi'm using c++. may i know ways to assign "numerical IP address" ? i'm trying to use the loopbakc address 127.0.0.1, and i tried the inet_aton, but i received multiple errors.
GeneralRe: SETTING UP NUMERICAL IP ADDRESS PinmemberEmiliano13-Jul-04 23:16 
GeneralRe: SETTING UP NUMERICAL IP ADDRESS Pinmembers31f21-Aug-06 5:51 
GeneralSETTING UP NUMERICAL IP ADDRESS Pinmemberdikads13-Jul-04 1:21 
hello, im new in socket programming. may i know ways to assign "numerical IP address" ? i'm trying to use the loopbakc address 127.0.0.1, and i tried the inet_aton, but i received multiple errors.
GeneralServer Search PinmemberWolfram Steinke12-Jun-04 23:06 
How would I implement a method by which the client could search for the server if you don't know it's name or address?
 
Happy programming!!
Generalfile transfer over internet Pinmemberzabiba18-May-04 6:30 
please can any one help me with making file transfer over internet connections using csocketfile

QuestionHow to send text file. PinmemberKmAshif17-Apr-04 19:16 
Hello,
I also need to receive text file from server.
Please help me by writing sample code or project.
Questionwhat sort af application ? PinsussAnonymous1-Feb-04 3:33 
hello,
 
sorry i'm a beginner and i would like to use your downloaded files but i don't know in which sort of project to include them in Visual C++ (MFC, Win 32 console ....??).
 
Indeed I have to implement an application client/server in TCP/IP then UDP, turning on a single machine in Java...
 
Thank you for your help !
AnswerRe: what sort af application ? PinmemberEmiliano1-Feb-04 22:49 
Generalsource port corrupted in sendto() Pinmemberembrt28-Jan-04 6:51 
Thanks for the clear explanation of sockets and your example.
 
I'm doing UDP communcations between two programs on two different PCs (pier-to-pier). I'm using the win socket api very similar to your code, except mine is connectionless. I'm watching the communications between the two programs using Ethereal.
 
Program-A sends a message to program-B (my program). My program-B sees the message and sends back a message to program-A. When I watch this exchange on Ethereal, I can see the ports used by the two programs. Program-A sends me the message with the correct source and destination ports defined. My program-B sends the message back to Program-A using the correct destination port, so the data gets there. But for some reason the source port in the data-gram that I send is new port number which appears to be arbitary.
 
When Program-A receives the message and sees the new port number in the datagram, it changes the remote port address it's using, and the next time it tries to send me a message, it sends it to the bogus port number, so I never see it. If I reset the comms on program-A and send a message again to my program-B, the bogus port number remains the same. If I restart my app, the bogus port number is different each time.
 
I checked the port address in the socket after I do the send and it reads correctly. And I'm not getting any Windows errors.
 
Got any ideas? Thanks in advance.

QuestionHow to Create Custmom windows and menus in UNIX Environment ? PinmemberChaitanya Kumar Pinninti28-Jan-04 0:14 
How to creatge customized windows and tool bars in UNIX environment using C&C++. How to use curses.h header file. C'd any body help me by giving some examples?
 
Chaitanya Kumar Pinninti,
Software Engineer,
AVON Technologies.
Questionwhat is the different between ? Pinmemberfindpin11-Jan-04 21:52 
hi,this article is good.
I also want study winsock,and i want know the different between
#pragma comment (lib,"ws2_32.lib")
and
#pragma comment (lib,"winsock32.lib")
 
work hard you will find
more fan
AnswerRe: what is the different between ? PinsussEmiliano12-Jan-04 0:23 
GeneralSending data by random from server to client PinmemberKelvin_tkw15-Dec-03 16:41 
How can 1 server send data that have same type of data by random to each client?It means each client will receive no a same data at the same time. The Data likes exam question. All the exam questions store in server database. When exam is started, server will send different exam question to each client. Thanks
GeneralRe: Sending data by random from server to client PinmemberEmiliano15-Dec-03 23:25 
Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130617.1 | Last Updated 26 Apr 2003
Article Copyright 2003 by Emiliano
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid