• Advertisement

netpumber

Member
  • Content count

    6
  • Joined

  • Last visited

Community Reputation

100 Neutral

About netpumber

  • Rank
    Newbie
  1. i should turn on TCP_NODELAY only to the client or in the server too ? Edit: I have made these changes in client [CODE]// Create a new socket to make a client connection. [b]BOOL bOpt = TRUE;[/b] ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); [b]setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY,(char*)&bOpt,sizeof(BOOL));[/b][/CODE] and before main loop ends in both (client & server) [CODE] } [b]SleepEx(10, FALSE);[/b] } // Main menu ends here[/CODE] The results still the same.
  2. So.. whats the problem with my new select() application ? Why the delay still exists ? Can anyone think something ?
  3. Hello again. After our conversation here i decide to give a try once again with select method. Here is the new code. I put 0 in timeout and also i use an array with sockets to avoid looping between all these integers. Server: [code] #include <WinSock2.h> #include <stdio.h> #include <time.h> main() { SOCKET ListeningSocket; SOCKET AcceptSocket; SOCKADDR_IN ServerAddr; SOCKADDR_IN ClientAddr; WSADATA wsaData; const unsigned short PORT = 4444; FD_SET fdread; FD_SET BackUpfdread; FD_SET fdwrite; FD_SET BackUpfdwrite; int maxDescriptor; SOCKET SocketArray[20]; int index = 0; int selectResults; int i,k; int clientAddrSize; int RecvBytes; int SentBytes; char SentBuff[500]; char RecvBuff[500]; struct timeval timeout; // Initialize Winsock2.2 WSAStartup(MAKEWORD(2,2),&wsaData); // Initialize Listening Socket ListeningSocket = socket(AF_INET,SOCK_STREAM,0); // Initialize ServerAddr ServerAddr.sin_family = AF_INET; ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); ServerAddr.sin_port = htons(PORT); // Bind the ServerAddr with ListeningSocket bind(ListeningSocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)); // Listening Socket listen(ListeningSocket,5); FD_ZERO(&fdread); FD_ZERO(&BackUpfdread); FD_ZERO(&fdwrite); FD_ZERO(&BackUpfdwrite); // Asign ListeningSocket at fdread FD_SET(ListeningSocket,&fdread); maxDescriptor = ListeningSocket; SocketArray[index] = ListeningSocket; index++; timeout.tv_sec = 0; timeout.tv_usec = 0; // Main loop starts here for(; ;) { BackUpfdread = fdread; BackUpfdwrite = fdwrite; selectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timeout); //printf("server select() OK\n"); if(selectResults == -1) { printf("Select() error"); WSACleanup(); return 0; } for(i=0;i<=index-1;i++) { //printf("%d\n",SocketArray[i]); if(FD_ISSET(SocketArray[i],&BackUpfdread)) { if(SocketArray[i] == ListeningSocket) // we have a new connection { clientAddrSize = sizeof(ClientAddr); AcceptSocket = accept(ListeningSocket,(SOCKADDR *)&ClientAddr,&clientAddrSize); // Add the newest accepted socket to the fdread and fdwrite sets. FD_SET(AcceptSocket,&fdread); FD_SET(AcceptSocket,&fdwrite); // Add the newest accepted socket into SocketArray SocketArray[index] = AcceptSocket; index++; // keep track of the maxDescriptor. if(AcceptSocket > maxDescriptor) { maxDescriptor = AcceptSocket; } printf("New connection from %s on socket %d\n", inet_ntoa(ClientAddr.sin_addr), AcceptSocket); }else{ // That means that the socket is not from a new conection and has something sent. memset(RecvBuff,0,sizeof(RecvBuff)); RecvBytes = recv(SocketArray[i], RecvBuff, sizeof(RecvBuff)-1, 0); if(RecvBytes > 0) // Some data received. { printf("Message Send.\n"); printf("Message was: %s\n",RecvBuff); for(k=0;k<=index-1;k++) { if(FD_ISSET(SocketArray[k],&BackUpfdwrite)) { if(SocketArray[k] != ListeningSocket && SocketArray[k] != SocketArray[i]) { memset(SentBuff,0,sizeof(SentBuff)); strcpy(SentBuff,RecvBuff); SentBytes = send(SocketArray[k],SentBuff,sizeof(SentBuff),0); } } } } } } } }// Main loop ends here }[/code] Client: [code]#include <WinSock2.h> #include <stdio.h> #include <time.h> main() { SOCKET ConnectSocket; SOCKET SocketArray[20]; SOCKADDR_IN ServerAddr; WSADATA wsaData; FD_SET fdwrite; FD_SET fdread; FD_SET BackUpfdread; FD_SET BackUpfdwrite; char server_address[20] = "192.168.1.4"; char SentBuff[500]; char RecvBuff[500]; const unsigned short PORT = 4444; int maxDescriptor; int index = 0; int SelectResults; int i; int RecvBytes; int SentBytes; struct timeval timeout; // Initialize Winsock 2.2 WSAStartup(MAKEWORD(2,2),&wsaData); // Initialize ServerAddr ServerAddr.sin_family = AF_INET; ServerAddr.sin_addr.s_addr = inet_addr(server_address); ServerAddr.sin_port = htons(PORT); // Create a new socket to make a client connection. ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // Clear the fd sets FD_ZERO(&fdread); FD_ZERO(&BackUpfdread); FD_ZERO(&fdwrite); FD_ZERO(&BackUpfdwrite); // Asign ConnectSocket into fdread and fdwrite. FD_SET(ConnectSocket,&fdread); FD_SET(ConnectSocket,&fdwrite); // Set timer timeout.tv_sec = 0; timeout.tv_usec = 0; maxDescriptor = ConnectSocket; SocketArray[index] = ConnectSocket; index++; // Make a connection to the server with socket s. if(connect(ConnectSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) { printf("Couldn't connect to the server\n"); } // Main loop starts here for(; ;) { BackUpfdread = fdread; BackUpfdwrite = fdwrite; memset(SentBuff, 0, sizeof(SentBuff)); printf("Write: "); gets_s(SentBuff, sizeof(SentBuff)); SelectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timeout); for(i=0;i<=index-1;i++) { // Something to read from server. if(FD_ISSET(SocketArray[i],&BackUpfdread) && SocketArray[i] == ConnectSocket) { RecvBytes = recv(SocketArray[i], RecvBuff, sizeof(RecvBuff), 0); if(RecvBytes > 0) { printf("%s\n",RecvBuff); // Cleaning the Receive Buffer memset(RecvBuff,0,sizeof(RecvBuff)); } } // Something to write. if(FD_ISSET(SocketArray[i],&BackUpfdwrite) && SocketArray[i] == ConnectSocket) { SentBytes = send(SocketArray[i], SentBuff,sizeof(SentBuff),0); // Cleaning the Sent Buffer memset(SentBuff,0,sizeof(SentBuff)); } } } // Main menu ends here }[/code] The problem is that i ve noticed that still there is a delay on message transfer. It looks like there are blocking sockets. Here is a pic. [img]http://img515.imageshack.us/img515/3237/64047117.png[/img]
  4. Thanks a lot for your answer hplus0603 . First of all i think that the second problem you referred to, will be solved using a struct that will save the socket number of each client and in the for loop i will use these numbers. As for the username sending i will find another way to do this. Finally i want you to tell me why to use select() and not WSAEventSelect method. As i read on net the first one uses more CPU than the other. [u] [/u]
  5. Yeah ok i ve read the [url="http://www.gamedev.net/index.php?app=forums&module=forums&section=rules&f=15"]FAQ[/url] but it talks mostly for select() method as i saw. The truth is that i have try the select method but there was a problem with the message send time. Here is my code for my select() try. Server: [code].... // Listening //iMode = 1; // If iMode!=0, non-blocking mode is enabled. listen(ListeningSocket,5); //ioctlsocket(ListeningSocket,FIONBIO,&iMode); // Enable the non-locking mode. // Clear the two fd sets FD_ZERO(&fdread); FD_ZERO(&BackUpfdread); FD_ZERO(&fdwrite); FD_ZERO(&BackUpfdwrite); // Asign the ListeningSocket with fdread. FD_SET(ListeningSocket,&fdread); FD_SET(ListeningSocket,&fdwrite); // Set as maxDescriptor ListeningSocket. maxDescriptor = ListeningSocket; // Setup timer. timeout.tv_sec = 2; timeout.tv_usec = 5000; // Main loop starts here. for(; ; ) { // Keep a backup of FD set cause select() erases it, if there's nothing to do. BackUpfdread = fdread; BackUpfdwrite = fdwrite; selectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timeout); if(selectResults == -1) { printf("Select() error"); WSACleanup(); return 0; } // Check the fdread set for alive connections for(i=0;i<=maxDescriptor;i++) { if(FD_ISSET(i,&BackUpfdread)) { if(i == ListeningSocket) // That means we have a NEW CONNECTION and must hadle it. { ClientAddrSize = sizeof(ClientAddr); AcceptSocket = accept(ListeningSocket,(SOCKADDR *)&ClientAddr,&ClientAddrSize); if(AcceptSocket == -1) { printf("Winsock error - Unable to accept socket"); WSACleanup(); return 0; } // Add the newest socket in the fdread set. FD_SET(AcceptSocket,&fdread); FD_SET(AcceptSocket,&fdwrite); // Keep track of the maxDescriptor. if(AcceptSocket > maxDescriptor) { maxDescriptor = AcceptSocket; } // Receiving the username from the new client. memset(username,0,sizeof(username)); recv(AcceptSocket,username,sizeof(username),0); printf("New connection (username: %s) from %s on socket %d\n", username, inet_ntoa(ClientAddr.sin_addr), AcceptSocket); // Send Welcome Message. send(AcceptSocket,msg,sizeof(msg),0); }else{ // That means that the socket (i) isn't from a new connection and has something sent. RecvBytes = recv(i, RecvBuff, sizeof(RecvBuff)-1, 0); if(RecvBytes == -1) { printf("Winsock error - Cannot receive data from client"); WSACleanup(); return 0; } if(RecvBytes == 0) { printf("Socket %d hung up\n", i); // Shutdown Socket shutdown(i,SD_RECEIVE); // Clear fdread. FD_CLR(i, &fdread); } if(RecvBytes > 0) { printf("Message Send.\n"); printf("Message was: %s\n",RecvBuff); for(k=0;k<=maxDescriptor;k++) { if(FD_ISSET(k,&BackUpfdwrite)) { memset(SentBuff,0,sizeof(SentBuff)); strcpy(SentBuff,RecvBuff); SentBytes = send(k,SentBuff,sizeof(SentBuff),0); } } } } } } } // Main loop ends here. ...[/code] Client: [code] .... // Initialize Winshock 2.2 WSAStartup(MAKEWORD(2,2),&wsaData); // Create a new socket to make a client connection. ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // Initialize Servers SOCKADDR_IN ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(port); ServerAddr.sin_addr.s_addr = inet_addr(server_address); // Clear the fd sets FD_ZERO(&fdread); FD_ZERO(&BackUpfdread); FD_ZERO(&fdwrite); FD_ZERO(&BackUpfdwrite); // Asign the ListeningSocket with fdread and fdwrite. FD_SET(ConnectSocket,&fdread); FD_SET(ConnectSocket,&fdwrite); // Set as maxDescriptor ListeningSocket. maxDescriptor = ConnectSocket; // Setup timer. timer.tv_sec = 2; timer.tv_usec = 5000; //iMode = 1; // If iMode!=0, non-blocking mode is enabled. //ioctlsocket(ConnectSocket,FIONBIO,&iMode); // Enable the non-locking mode. // Make a connection to the server with socket s. connect(ConnectSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)); // Send the username to server. send(ConnectSocket,username,strlen(username),0); // Receive Welcome Message From Server (If any..) RecvBytes = recv(ConnectSocket,RecvBuff,sizeof(RecvBuff),0); if(RecvBytes > 0) { printf("%s",RecvBuff); // Cleaning the Receive Buffer memset(RecvBuff,0,sizeof(RecvBuff)); } // Main loop starts here for(; ; ) { // Copy the fdread into BackUpfdread and fdwrite to BackUpfdwrite. BackUpfdread = fdread; BackUpfdwrite = fdwrite; SelectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timer); if(SelectResults == -1) { perror("Client-select() error!\n"); exit(1); } //printf("Client-select is OK\n"); //Check if we have some data to read. if (FD_ISSET(ConnectSocket, &BackUpfdread)) { RecvBytes = recv(ConnectSocket, RecvBuff, sizeof(RecvBuff), 0); if(RecvBytes > 0) { printf("%s\n",RecvBuff); // Cleaning the Receive Buffer memset(RecvBuff,0,sizeof(RecvBuff)); } } memset(SentBuff, 0, sizeof(SentBuff)); printf("Write: "); gets_s(SentBuff, sizeof(SentBuff)); //Check if we have some data to write. if (FD_ISSET(ConnectSocket, &BackUpfdwrite)) { SentBytes = send(ConnectSocket, SentBuff,sizeof(SentBuff),0); // Cleaning the Sent Buffer memset(SentBuff,0,sizeof(SentBuff)); } } // Main loop ends here ....[/code] and here is the image that shows the message transfer delay. [img]http://img402.imageshack.us/img402/6692/chatbq.png[/img] After these problems i decided to use the WSAEventSelect with event creation and blah blah as the tutorial posted before says..
  6. Hello. So a month now im searching in net different methods to create a chat client/server app. Clients will connect to the server and the server will send the message of each client to the rest. I use C and Visual studio 10 and finally i decided to use the async method. My app will be a simple console application so i will use WSAEventSelect instead of WSAAsyncSelect. I have found only [url="http://www.codeproject.com/KB/IP/networkevents.aspx"]this[/url] tutorial on net talking about this. Also i read and for IOCP but my knowledge is not enough for something like this. I ask you to tell me if you find my decision correct and if you have any tutorial or post on mind that can help me. Please let me know. Also any hint or suggestion is welcomed. Thanks in advance.
  • Advertisement