Multi-user server
-
I'm looking for multi-user server source code (tutorial) (C/C++, sockets, no MFC). Oh, I already know how to do multi connections the windows way (messages sent to my window when data is received), but that's not what I want. I know there are some here at codeproject but they all use MFC (yuck) and seem alot more complicated then what I've found so far. I found the original at www.planet-source-code.com (I've re-done and simplified it for this post):
SOCKET ServerSocket; SOCKADDR_IN server_address; FD_SET masterSet; HANDLE ThreadHandle; DWORD ThreadID; int RetVal = 0; DWORD WINAPI acceptingThreadProcedure(LPVOID ServerSocket) { SOCKET* Socket = (SOCKET*)ServerSocket; SOCKET ClientSocket; while(1) { ClientSocket = accept(*Socket,0,0); FD_SET(ClientSocket,&masterSet); printf("Client on %d connected\n",ClientSocket); } return TRUE; } int InitServer() { WSADATA wsaData; WSAStartup(MAKEWORD(1,0),&wsaData); ServerSocket = socket(PF_INET,SOCK_STREAM,0); server_address.sin_family = AF_INET; server_address.sin_port = 4200; server_address.sin_addr.s_addr = INADDR_ANY; bind(ServerSocket,(SOCKADDR*)&server_address,sizeof(SOCKADDR_IN)); listen(ServerSocket,5); ThreadHandle = CreateThread(NULL,0,acceptingThreadProcedure,&ServerSocket,0,&ThreadID); Sleep(100); FD_ZERO(&masterSet); FD_SET pollingSet; timeval waitTime; waitTime.tv_sec = 0; waitTime.tv_usec = 0; SOCKET clientSocket; unsigned long BufferSize; while(1) { pollingSet = masterSet; if(pollingSet.fd_count == 0) continue; RetVal = select(pollingSet.fd_count,&pollingSet,NULL,NULL,&waitTime); if(RetVal == 0) continue; for(unsigned int i = 0; i < pollingSet.fd_count; i++) { clientSocket = pollingSet.fd_array[i]; //This was his Idea recv(clientSocket,(LPSTR)&BufferSize,sizeof(BufferSize),0); BufferSize = ntohl(BufferSize); LPSTR Buffer = new char[BufferSize]; recv(clientSocket,(LPSTR)Buffer,BufferSize,0); Buffer[BufferSize] = '\0'; printf("Client %d: %s\n",clientSocket,Buffer); delete[] Buffer; } } }
I've been looking for tutorials that teach it with FD_SET and select but havn't found anything yet. Does anyone know of a good tutorial? P.S. The reason I'm looking for something more than what I've found is that the current code (above) doesn't have a wa -
I'm looking for multi-user server source code (tutorial) (C/C++, sockets, no MFC). Oh, I already know how to do multi connections the windows way (messages sent to my window when data is received), but that's not what I want. I know there are some here at codeproject but they all use MFC (yuck) and seem alot more complicated then what I've found so far. I found the original at www.planet-source-code.com (I've re-done and simplified it for this post):
SOCKET ServerSocket; SOCKADDR_IN server_address; FD_SET masterSet; HANDLE ThreadHandle; DWORD ThreadID; int RetVal = 0; DWORD WINAPI acceptingThreadProcedure(LPVOID ServerSocket) { SOCKET* Socket = (SOCKET*)ServerSocket; SOCKET ClientSocket; while(1) { ClientSocket = accept(*Socket,0,0); FD_SET(ClientSocket,&masterSet); printf("Client on %d connected\n",ClientSocket); } return TRUE; } int InitServer() { WSADATA wsaData; WSAStartup(MAKEWORD(1,0),&wsaData); ServerSocket = socket(PF_INET,SOCK_STREAM,0); server_address.sin_family = AF_INET; server_address.sin_port = 4200; server_address.sin_addr.s_addr = INADDR_ANY; bind(ServerSocket,(SOCKADDR*)&server_address,sizeof(SOCKADDR_IN)); listen(ServerSocket,5); ThreadHandle = CreateThread(NULL,0,acceptingThreadProcedure,&ServerSocket,0,&ThreadID); Sleep(100); FD_ZERO(&masterSet); FD_SET pollingSet; timeval waitTime; waitTime.tv_sec = 0; waitTime.tv_usec = 0; SOCKET clientSocket; unsigned long BufferSize; while(1) { pollingSet = masterSet; if(pollingSet.fd_count == 0) continue; RetVal = select(pollingSet.fd_count,&pollingSet,NULL,NULL,&waitTime); if(RetVal == 0) continue; for(unsigned int i = 0; i < pollingSet.fd_count; i++) { clientSocket = pollingSet.fd_array[i]; //This was his Idea recv(clientSocket,(LPSTR)&BufferSize,sizeof(BufferSize),0); BufferSize = ntohl(BufferSize); LPSTR Buffer = new char[BufferSize]; recv(clientSocket,(LPSTR)Buffer,BufferSize,0); Buffer[BufferSize] = '\0'; printf("Client %d: %s\n",clientSocket,Buffer); delete[] Buffer; } } }
I've been looking for tutorials that teach it with FD_SET and select but havn't found anything yet. Does anyone know of a good tutorial? P.S. The reason I'm looking for something more than what I've found is that the current code (above) doesn't have a waWell if you don't like MFC, try this unix sample: /* * ClockServer.c * sample Unix (SCO) clock server for pcsclock */ #include #include #include #include /* network includes */ #include #include #include #include /* PCS specific */ #include "token.h" #include "unixser.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* the default port */ int Port = 9999; // The socket int Socket; // The connection the child talks through int NewConnection; int SerialPort, Opened; char Buf[BUFSIZ]; enum tagCOMMANDS { UNKNOWN = -1, wOPEN, wCLOSE }; KEYWORDS KeyWords[]= { "open", 4, // PCSClock sends 'CLOSE' just before it does so "CLOSE", 5, NULL, 0 }; /* * Trim a string of spaces (Control characters remain) */ char *Trim(char *String) { int sLen; if(String != (char *)NULL) { sLen = 0; while(*(String + sLen) == ' ') sLen++; if(sLen) strcpy(String, String + sLen); if((sLen = strlen(String)) > 0) { while(sLen && *(String + sLen - 1) == ' ') { *(String + sLen - 1) = 0; sLen--; } } } return(String); } int InterpCommand(char *Buf) { char *cp = Buf; char Token[128]; if(GetToken(&cp, Token) != FINISHED) { switch(IsReservedVar(Token, KeyWords)) { case wOPEN: if(!Opened) { fprintf(stderr, "Opening %s\n", cp); SerialPort = ComOpen(Trim(cp), 256, 256); if(SerialPort >= 0) { if(ComSetParams(SerialPort, 9600, NONE, 8, 1, NONE) == OK) { write(NewConnection, "OK", 2); Opened = TRUE; } } if(!Opened) { write(NewConnection, "Fail", 4); perror("Open port failed"); } } break; case wCLOSE: if(Opened) ComClose(SerialPort); Opened = FALSE; return(FALSE); default: fprintf(stderr, "unknown command %s\n", Buf); break; } } return(TRUE); } int main(int argc, char **argv) { struct sockaddr_in Sock_IN; if(argc == 2) { int Tmp; Tmp = atoi(argv[1]); if(Tmp > 0) Port = Tmp; } if((Socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket() failed"); exit(1); } memset(&Sock_IN, 0, sizeof(Sock_IN)); Sock_IN.sin_family = AF_INET; Sock_IN.sin_port = htons(Port); Sock_IN.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(Socket, (struct sockaddr *)&Sock_IN, sizeof(S