-
Multiple Clients Winsock
Heya.
I managed to do a simple client-server-chat thingie... now I'm trying to make it for several clients at once (5 to begin with... mebbe more later when I get it to work!)
well my question is, do I have to make my server application multithreaded to do that, or is it possible somehow to do it in 1 thread.
say, have a loop that loops through the clients using the SAME socket evrytime and looking if they're sending / requesting sumthin... whoa... it's really causing me some headaches :)
Thanks,
PrivatePanic
-
you need to look at select()
look here
http://www.ecst.csuchico.edu/~beej/guide/net/
This is an excellent sockets tutorial I used this to learn sockets.
It has all the information you'll need. The source code is *nix but it tells you exactly how to get it working under windows or any other OS and all the code does compile when you use winsock as Ive compiled and run each example on a win machine.
I say look at select in this tutorial and maybe even read the whole thing to make sure you understand it.
select was really hard for me to grasp in to begin with but it eventually makes sense.
-
Well thanks for the advice!
I know now I have to fill a fd_set struct with all the client's sockets...
but I don't know how to implement the select-function, or, in other words, where in my code I have to call it.
I'm using WSAAsyncSelect to have an user Msg called when socket events occur, btw.
If you'd give me a further hint how/where to insert the select function to do the task I need it for, I'd be very grateful :D
Here my routine to react on the socket events so far:
Code:
...
case WM_ONSOCKET:
if (WSAGETSELECTERROR(lParam))
{ // error
WSACleanup ();
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
char readbuff[2000];
int rlen;
rlen = recv(cli_sock,readbuff,2000,0);
readbuff[rlen] = 0;
strcat(readbuff,"\r\n");
send(cli_sock, readbuff, rlen, 0);
break;
case FD_ACCEPT:
char pszTemp[255];
sprintf(pszTemp, "A client sends a connection attempt.\r\n" );
OutputLine(hEdit, pszTemp);
int ilen; ilen = sizeof(cli_addr);
cli_sock = accept( serv_sock, (struct sockaddr*)&cli_addr, &ilen );
sprintf(pszTemp, "Client connected [IP:%s][S:%d]\r\n", inet_ntoa(cli_addr.sin_addr), (INT) cli_sock );
OutputLine(hEdit, pszTemp);
break;
case FD_CLOSE:
OutputLine(hEdit, "Client disconnected!\r\n");
break;
}
break;
......
cli_sock is the Client's socket. OutputLine is just an own-written function to CAT a string into an edit control.
-
you don't need to be multi threaded on a server but it helps sometimes. depends on your architecture.
FD_READ comes in with the wParam being the socket that it's coming in on. You can have a list of connections associated with their socket IDs no need for a thread per socket.
Threads are great when there is some procedure that is going to take a long time though. servers shouldn't be held up for a long time just because of some single complex request.
-
Thanks for the advice with the wParam of FD_READ, let's see how far this brings me :D
well I'm planning to do a simple multiplayer text-only game so there's no time critical stuff going to be.
Thanks anyway, great help so far!
-
Yeah it works, thanks a lot!
BTW, not only FD_READ sends the socket nr. as its wParam, every FD_... Message does! That way, I can also see which client disconnects etc.!
Again, thanks :D
-
glad i could be of service