Thread: Server - All Clients Send.

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    16

    Server - All Clients Send.

    Yeah...I know this has been talked about before, but the examples I saw used a diffrent method of storing connected clients, so I failed trying to convert their examples. But basicly I need to find a way to send a message to everyone once the server has recieved it. I know the other examples I saw used array's to store clients while this programs uses a set. I know that somehow I have to run through the set, sending a message to all the clients listed, using a loop. But I am not toally sure how that is done.


    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <winsock2.h>
    
    using std::cout;
    using std::cin;
    int startup(unsigned short port);
    int main();
    int cleanup(int socket);
    HANDLE threadHandle;
    HANDLE mutexHandle;
    FD_SET masterSet;
    bool gQuitFlag = false;
    
    int acceptthread(int* serverSocket)
    {
        int serversocket = *serverSocket;
        for (;;)
        {
            unsigned int clientsocket = accept(serversocket, 0, 0);
            cout<<"Waiting to accept connnections...\n";
            if (clientsocket == SOCKET_ERROR)
              {
                  cout<<"Error! Server failed to accept.\n";
                  gQuitFlag = true;
                  system("pause");
                  return 0;
              }
            else
              {
                  WaitForSingleObject(mutexHandle, INFINITE);
                  FD_SET(clientsocket, &masterSet);
                  ReleaseMutex(mutexHandle);
                  cout<<"Client Connected\n";
              }    
        } 
    }    
    
    int main()
    {
      int serversocket;
      serversocket = startup(65050); 
      if (serversocket == -1) 
      {
    		cout<<"Server failed to start.\nStopping Program.\n";
            system("pause");
            return 0;
      }
      mutexHandle = CreateMutex(NULL, false, NULL);
      if (mutexHandle == NULL) 
      {
    		cout<<"Failed to create mutex.\n";
    		cleanup(serversocket);
    		return 0;
      }
      int threadId;
      threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)acceptthread, &serversocket, 0, (LPDWORD)&threadId);
      if (threadHandle == NULL)
      {
    		cout<<"Acceptence tread failed to start.\n";
    		cleanup(serversocket);
    		return 0;
      }
      Sleep(100);
      FD_ZERO(&masterSet);
      for (;;)
      {
          if (gQuitFlag)
          {
    			break;
    	  }
          WaitForSingleObject(mutexHandle, INFINITE);
          FD_SET pollingSet = masterSet;
          ReleaseMutex(mutexHandle);
          if (pollingSet.fd_count == 0)
          {
    	      continue;
    	  }
    	  timeval waitTime;
    	  waitTime.tv_sec = 0;
    	  waitTime.tv_usec = 0;
    	  int result = select(pollingSet.fd_count, &pollingSet, NULL, NULL, &waitTime);
    	  if (result == 0)
          {
              continue;
          }
          if (result == SOCKET_ERROR)
          {
              cout<<"Failed to select.\n";
    		  continue;
    	  }
    	  for (unsigned int i = 0; i < pollingSet.fd_count; i++)
          {
              unsigned int clientsocket = pollingSet.fd_array[i];   
              int numbytes;
              #define MAX_MESSAGE_SIZE 4096
              char buffer[MAX_MESSAGE_SIZE];
              unsigned long messagesize;
              numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);  
              if (numbytes == SOCKET_ERROR)
              {
                  cout<<"Error! Failed to receive message size.\n";
                  int error = WSAGetLastError();
                  if (error == WSAECONNRESET)
                  {
    					WaitForSingleObject(mutexHandle, INFINITE);
    					FD_CLR(clientsocket, &masterSet);
    					ReleaseMutex(mutexHandle);
    					closesocket(clientsocket);
    					cout<<"Client Disconnected.\n";
                        continue;
    			  }
                  else
                  {
                      cout<<"Recieve message failed.\n";
                      gQuitFlag = true;
                      system("pause");
    		          break;
                  }			
              } 
              if (numbytes==0)
              {
                  WaitForSingleObject(mutexHandle, INFINITE);
                  FD_CLR(clientsocket, &masterSet);
                  ReleaseMutex(mutexHandle);
    		  	  closesocket(clientsocket);
                  cout<<"Client Disconnected.\n";
                  continue;
    		  }
      		  messagesize = ntohl(messagesize);
      		  numbytes = recv(clientsocket, buffer, messagesize, 0);
          	  if (numbytes == SOCKET_ERROR)
          	  {   
                  cout<<"Error! Recieve message failed.\n";
                  gQuitFlag = true;
                  system("pause");
    			  break;
              }
              buffer[messagesize] = '\0'; 
              cout<<"Message Received:"<<buffer<<"\n"; 
              if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
              {
                  cout<<"Failed to send message.\n";
              }  
          }           
      }  
    }
    
    int startup(unsigned short port)
    {
      int error;  
      WSAData wsaData;
      if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
        {
            cout<<"Error! Winsock failed to start.\n";
            return -1;
        }
      cout<<"Winsock started.\n";
      int serversocket = socket(AF_INET, SOCK_STREAM, 0);
      if (serversocket == SOCKET_ERROR)
        {
            cout<<"Error! Failed to create socket.\n";
            return -1;
        }
      cout<<"Socket created.\n";
      struct sockaddr_in server;
      server.sin_family = AF_INET;
      server.sin_port = htons(port);
      server.sin_addr.s_addr = INADDR_ANY;
    
      if (bind(serversocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        {
            cout<<"Error! Socket failed to bind.\n";
            closesocket(serversocket);
            return -1;
        }
      cout<<"Bind completed.\n";
      if (listen(serversocket, 5) == SOCKET_ERROR)
        {
            cout<<"Error! Failed to listen on socket.\n";
            closesocket(serversocket);
    		return -1;
        }
      cout<<"Listen Successful.\n";
      cout<<"Server Started\n";
      return serversocket;
    }
    
    int cleanup(int socket)
    {
      WaitForSingleObject(threadHandle, INFINITE);
      CloseHandle(threadHandle);
      CloseHandle(mutexHandle);
      closesocket(socket);
      WSACleanup();
      cout<<"Clean up complete.\n";
      system("PAUSE");
    }
    I got most of this code off a tutorial that I am reading but I have edited to my liking and purpose

  2. #2
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    an fd_set is generally only used to pass the sockets you wish to check for readability/writability to select()

    It's not a good idea to use an fd_set to store your actual list of connected clients because when you pass the fd_set to select() it's contents is modified to only contain the sockets which have data waiting (readability) or are able to accept data (writability). Normally you'd construct your fd_set from your list of clients before you call select(), or as you've done, construct a 'master' fd_set from which you create a temporary fd_set for select() to work with each loop.

    There's many different ways to store your connected clients list, depending on how you choose to design your server, but if you're just writing a program to experiment, i'd say just have an array of sockets of a fixed size (which can then be your max number clients), to keep it simple. It would also be possible to use your masterSet fd_set as a list of your connected clients I think, and loop through that, although I haven't ever tried to do that. I'd recommend having a seperate list of connections.

    One error I've spotted in your code is the call to recv()

    numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);

    try

    numbytes = recv(clientsocket, buffer, sizeof(buffer), 0);

    you want to pass a reference to somewhere it can store the recieved data (param 2) and the size of the array that it can fill with the data.

    I'll have a good look through when I have a bit more time. Haven't done any sockets programming for a while so I need a bit of a refresher myself...

    Hope that helps for now.

    Dan
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  3. #3
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    One other error I just spotted

    Remember 'FD_SET' is a macro for adding sockets to an fd_set and 'fd_set' is the actual structure for an fd_set.

    So you'd want to declare your fd_sets like so:

    fd_set masterSet;
    fd_set pollingSet = masterSet;

    (notice no caps)
    Last edited by codec; 09-23-2004 at 12:34 PM.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  4. #4
    Registered User
    Join Date
    Nov 2003
    Posts
    16
    Quote Originally Posted by codec
    an fd_set is generally only used to pass the sockets you wish to check for readability/writability to select()

    It's not a good idea to use an fd_set to store your actual list of connected clients because when you pass the fd_set to select() it's contents is modified to only contain the sockets which have data waiting (readability) or are able to accept data (writability). Normally you'd construct your fd_set from your list of clients before you call select(), or as you've done, construct a 'master' fd_set from which you create a temporary fd_set for select() to work with each loop.

    There's many different ways to store your connected clients list, depending on how you choose to design your server, but if you're just writing a program to experiment, i'd say just have an array of sockets of a fixed size (which can then be your max number clients), to keep it simple. It would also be possible to use your masterSet fd_set as a list of your connected clients I think, and loop through that, although I haven't ever tried to do that. I'd recommend having a seperate list of connections.

    One error I've spotted in your code is the call to recv()

    numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);

    try

    numbytes = recv(clientsocket, buffer, sizeof(buffer), 0);

    you want to pass a reference to somewhere it can store the recieved data (param 2) and the size of the array that it can fill with the data.

    I'll have a good look through when I have a bit more time. Haven't done any sockets programming for a while so I need a bit of a refresher myself...

    Hope that helps for now.

    Dan
    numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);

    that snippet of code is used becasue the client and server can send messages of variable size. And i dont think that the code you sugested can do that. Basicly the program recives the size then it acctually sends the message

  5. #5
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    Quote Originally Posted by mill1k
    numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);

    that snippet of code is used becasue the client and server can send messages of variable size. And i dont think that the code you sugested can do that. Basicly the program recives the size then it acctually sends the message
    If you're trying to store the size of the recieved data in messagesize, I'm pretty sure it's not going to do that. If it does it's a very strange and not necessarily reliable way. It'll fill numbytes with the amount of data recieved (unless the remote closes the connection or there's an error, which you already handle) so you don't need to use two calls to recv(), just the one that I suggested and use numbytes as your messagesize.

    After looking at your code more closely I see that you do actually get the data at a later stage. Only had a chance to have a quick look earlier and your code isn't the most readable ever.

    The information I gave you earlier is still useful for your original problem however. Had any luck?
    Last edited by codec; 09-23-2004 at 05:44 PM.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  6. #6
    Registered User
    Join Date
    Nov 2003
    Posts
    16
    I turns out that it does use a array to store the clients, so I tried a snippet of code that ran through the entire array looking for clients to send to.
    Code:
    for (unsigned int i = 0; i < pollingSet.fd_count; i++)
              {   
                  clientsocket = pollingSet.fd_array[i];
                  if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
                  {
                      cout<<"Failed to send message.\n";
                  }
              }
    If I run two clients and send some messages i get the following
    Clients 1: (Send) Hi
    Server: (Wait)
    Clients 2: (Wait) (Send) Hello
    Server: (Recv) Hi
    Server: (Recv) Hello
    Clients 1: (Recv) Hi
    Clients 2: (Recv) Hello
    Clients 1: (Send) Nice to meet you
    Server: (Wait)
    Clients 2: (Wait) (Send) You too
    Server: (Recv) Nice to meet you
    Server: (Recv) You too
    Clients 1: (Recv) You too meet you
    Clients 2: (Recv) Hiu too


    The server is sending the messages to the clients but it seem that the clients combine the messages they send with the one they recieve. I am not sure why the server and client 2 wait.

    Client:

    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <string.h>
    
    using std::cout;
    using std::cin;
    int startup(unsigned short port, const char* serveraddress);
    int main();
    int cleanup(int socket);
    
    int main()
    {
      char serverip[128];
      cout<<"Input server IP:";
      cin.getline(serverip, 127);
      cout<<serverip;
      int clientsocket;
      clientsocket = startup(65050, serverip); 
      if (clientsocket == -1) 
      {
    		cout<<"Client failed to start.\nStopping program.\n";
    		cleanup (clientsocket);
            return 0;
      }
      int numbytes;
      #define MAX_MESSAGE_SIZE 4096
      char buffer[MAX_MESSAGE_SIZE];
      cout<<"Type messages bellow and press enter to send, To exit type 'quit'.\n";
      for (;;)
      {
            gets(buffer);
            if (strcmp(buffer, "quit") == 0)
            {
                break;
            }
            unsigned long messagesize = strlen(buffer);
            messagesize = htonl(messagesize);
            if ((numbytes = send(clientsocket, (char*)&messagesize, sizeof(messagesize), 0)) == SOCKET_ERROR)
            {
                cout<<"Failed to send message size.\n";
    		}        
    		messagesize = htonl(messagesize);
    		if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
            {
                cout<<"Send message failed.\n";
    		}
    		numbytes = recv(clientsocket, buffer, messagesize, 0);
            if (numbytes == SOCKET_ERROR)
            {   
                cout<<"Error! Failed to recieve message.\n";
    		    continue;
            } 
            cout<<"Message Received:"<<buffer<<"\n"; 
      }   
      cleanup (clientsocket);
    }
    
    int startup(unsigned short port, const char* serveraddress)
    {
      int error;  
      WSAData wsaData;
      if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
        {
            cout<<"Error! Winsock failed to start.\n";
            return -1;
        }
      cout<<"Winsock started.\n";
      int clientsocket = socket(AF_INET, SOCK_STREAM, 0);
      if (clientsocket == SOCKET_ERROR)
        {
            cout<<"Error! Failed to create socket.\n";
            return -1;
        }
      cout<<"Socket created.\n";
      struct hostent *host_entry;
      
      if ((host_entry = gethostbyname(serveraddress)) == NULL)
        {
    		cout<<"Localising of host failed.\n";
    		return -1;	
        }
      cout<<"Localization achevied.\n";
      
      struct sockaddr_in server;
      server.sin_family = AF_INET;
      server.sin_port = htons(port);
      server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
    
     if (connect(clientsocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        {
    		cout<<"Error! Failed to connect to server.\n";
    		return -1;
    	}
      cout<<"Conenction acheived.\n"; 
      cout<<"Client Started\n";
      return clientsocket;
    }
    
    int cleanup(int socket)
    {
      closesocket(socket);
      WSACleanup();
      cout<<"Clean up complete.\n";
      system("PAUSE");
    }
    Server:

    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <winsock2.h>
    
    using std::cout;
    using std::cin;
    int startup(unsigned short port);
    int main();
    int cleanup(int socket);
    HANDLE threadHandle;
    HANDLE mutexHandle;
    FD_SET masterSet;
    bool gQuitFlag = false;
    
    int acceptthread(int* serverSocket)
    {
        int serversocket = *serverSocket;
        for (;;)
        {
            unsigned int clientsocket = accept(serversocket, 0, 0);
            cout<<"Waiting to accept connnections...\n";
            if (clientsocket == SOCKET_ERROR)
              {
                  cout<<"Error! Server failed to accept.\n";
                  gQuitFlag = true;
                  system("pause");
                  return 0;
              }
            else
              {
                  WaitForSingleObject(mutexHandle, INFINITE);
                  FD_SET(clientsocket, &masterSet);
                  ReleaseMutex(mutexHandle);
                  cout<<"Client Connected\n";
              }    
        } 
    }    
    
    int main()
    {
      int serversocket;
      serversocket = startup(65050); 
      if (serversocket == -1) 
      {
    		cout<<"Server failed to start.\nStopping Program.\n";
            system("pause");
            return 0;
      }
      mutexHandle = CreateMutex(NULL, false, NULL);
      if (mutexHandle == NULL) 
      {
    		cout<<"Failed to create mutex.\n";
    		cleanup(serversocket);
    		return 0;
      }
      int threadId;
      threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)acceptthread, &serversocket, 0, (LPDWORD)&threadId);
      if (threadHandle == NULL)
      {
    		cout<<"Acceptence tread failed to start.\n";
    		cleanup(serversocket);
    		return 0;
      }
      Sleep(100);
      FD_ZERO(&masterSet);
      for (;;)
      {
          if (gQuitFlag)
          {
    			break;
    	  }
          WaitForSingleObject(mutexHandle, INFINITE);
          FD_SET pollingSet = masterSet;
          FD_SET pollingSet2 = masterSet;
          ReleaseMutex(mutexHandle);
          if (pollingSet.fd_count == 0)
          {
    	      continue;
    	  }
    	  timeval waitTime;
    	  waitTime.tv_sec = 0;
    	  waitTime.tv_usec = 0;
    	  int result = select(pollingSet.fd_count, &pollingSet, &pollingSet, NULL, &waitTime);
    	  if (result == 0)
          {
              continue;
          }
          if (result == SOCKET_ERROR)
          {
              cout<<"Failed to select.\n";
    		  continue;
    	  }
    	  for (unsigned int i = 0; i < pollingSet.fd_count; i++)
          {
              unsigned int clientsocket = pollingSet.fd_array[i];   
              int numbytes;
              #define MAX_MESSAGE_SIZE 4096
              char buffer[MAX_MESSAGE_SIZE];
              unsigned long messagesize;
              numbytes = recv(clientsocket, (char*)&messagesize, sizeof(messagesize), 0);  
              if (numbytes == SOCKET_ERROR)
              {
                  cout<<"Error! Failed to receive message size.\n";
                  int error = WSAGetLastError();
                  if (error == WSAECONNRESET)
                  {
    					WaitForSingleObject(mutexHandle, INFINITE);
    					FD_CLR(clientsocket, &masterSet);
    					ReleaseMutex(mutexHandle);
    					closesocket(clientsocket);
    					cout<<"Client Disconnected.\n";
                        continue;
    			  }
                  else
                  {
                      cout<<"Recieve message failed.\n";
                      gQuitFlag = true;
                      system("pause");
    		          break;
                  }			
              } 
              if (numbytes==0)
              {
                  WaitForSingleObject(mutexHandle, INFINITE);
                  FD_CLR(clientsocket, &masterSet);
                  ReleaseMutex(mutexHandle);
    		  	  closesocket(clientsocket);
                  cout<<"Client Disconnected.\n";
                  continue;
    		  }
      		  messagesize = ntohl(messagesize);
      		  numbytes = recv(clientsocket, buffer, messagesize, 0);
          	  if (numbytes == SOCKET_ERROR)
          	  {   
                  cout<<"Error! Recieve message failed.\n";
                  gQuitFlag = true;
                  system("pause");
    			  break;
              }
              buffer[messagesize] = '\0'; 
              cout<<"Message Received:"<<buffer<<"\n"; 
              for (unsigned int i = 0; i < pollingSet.fd_count; i++)
              {   
                  clientsocket = pollingSet.fd_array[i];
                  if ((numbytes = send(clientsocket, buffer, messagesize, 0)) == SOCKET_ERROR)
                  {
                      cout<<"Failed to send message.\n";
                  }
              }            
          }           
      }  
    }
    
    int startup(unsigned short port)
    {
      int error;  
      WSAData wsaData;
      if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
        {
            cout<<"Error! Winsock failed to start.\n";
            return -1;
        }
      cout<<"Winsock started.\n";
      int serversocket = socket(AF_INET, SOCK_STREAM, 0);
      if (serversocket == SOCKET_ERROR)
        {
            cout<<"Error! Failed to create socket.\n";
            return -1;
        }
      cout<<"Socket created.\n";
      struct sockaddr_in server;
      server.sin_family = AF_INET;
      server.sin_port = htons(port);
      server.sin_addr.s_addr = INADDR_ANY;
    
      if (bind(serversocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        {
            cout<<"Error! Socket failed to bind.\n";
            closesocket(serversocket);
            return -1;
        }
      cout<<"Bind completed.\n";
      if (listen(serversocket, 5) == SOCKET_ERROR)
        {
            cout<<"Error! Failed to listen on socket.\n";
            closesocket(serversocket);
    		return -1;
        }
      cout<<"Listen Successful.\n";
      cout<<"Server Started\n";
      return serversocket;
    }
    
    int cleanup(int socket)
    {
      WaitForSingleObject(threadHandle, INFINITE);
      CloseHandle(threadHandle);
      CloseHandle(mutexHandle);
      closesocket(socket);
      WSACleanup();
      cout<<"Clean up complete.\n";
      system("PAUSE");
    }


    Note: This is my longest post ever XD

  7. #7
    Registered User
    Join Date
    Nov 2003
    Posts
    16
    After thinking about it at work I reliezed a problem. The clients can't recieve unless they send..so it looks like i am going to need to find a threading tutorial so i can create a recieving thread.

  8. #8
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    If you want your server to send out whatever it recieves from one client to every client then loop through your master fd_set and not the polling set as the contents of this would have been modified by the select() function call to contain only the sockets whcih having data waiting.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  9. #9
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    Also, if designed correctly, a server app using the select() function that is as simple as you're doing shouldn't need any extra threads at all. You can do away with the accept thread by adding your listening socket to your fd_set you pass to select(), then whenever a connection is waiting on your listening socket select() will let you know.

    [edit] You can use this FD_ISSET() macro to check to see if it's your listening socket that's got a connection waiting [/edit]

    All this information, and loads more can be obtained just by looking the the MSDN Winsock 2 section.
    Last edited by codec; 09-28-2004 at 09:38 AM.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  10. #10
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>If you're trying to store the size of the recieved data in messagesize, I'm pretty sure it's not going to do that. If it does it's a very strange and not necessarily reliable way.
    I'd just like to point out that this is a perfectly valid way of sending and receiving data. &messagesize is a pointer to the beginning of the memory which holds the value of messagesize, which is really just a string of bytes. By converting it to char*, it becomes a valid memory address for use with recv(), and recv() simply interprets it as an array of char - an array of _bytes_ (actually unsigned char is the only true byte, but for our purposes char works too). So it receives the bytes from the server and writes them into messagesize's memory location, and thus you have just received binary data directly into the desired variable.

    Also note, recv() isn't guaranteed to receive the whole packet in one call... you might only receive 2 bytes or 1, in which case it's your responsibility to make sure that you get the rest of the packet later.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  11. #11
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    Quote Originally Posted by Hunter2
    >>If you're trying to store the size of the recieved data in messagesize, I'm pretty sure it's not going to do that. If it does it's a very strange and not necessarily reliable way.
    I'd just like to point out that this is a perfectly valid way of sending and receiving data. &messagesize is a pointer to the beginning of the memory which holds the value of messagesize, which is really just a string of bytes. By converting it to char*, it becomes a valid memory address for use with recv(), and recv() simply interprets it as an array of char - an array of _bytes_ (actually unsigned char is the only true byte, but for our purposes char works too). So it receives the bytes from the server and writes them into messagesize's memory location, and thus you have just received binary data directly into the desired variable.
    That's easy to point out when you have the benefit of seeing all the relevant code I did not. Without seeing the client-side code, it was not possible to know he'd included the messagesize in his packet. Looking at the code on the server which simply sends the contents of the buffer without including messagesize back to the client, I'd say it was a fair assumption at the time.

    What Hunter2 said about your messages possibly being fragmented is just one of the many things you have to consider in writing a production quality server.
    Last edited by codec; 09-30-2004 at 08:31 AM.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  12. #12
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>That's easy to point out when you have the benefit of seeing all the relevant code I did not.
    Don't see what you mean... the code was in the first post he made.

    >>Without seeing the client-side code, it was not possible to know he'd included the messagesize in his packet.
    If you don't know the protocol, don't assume that the messagesize isn't sent... because it almost always is. And you can see later that he uses messagesize in recv() to determine the number of bytes to receive.

    Looking at the code on the server which simply sends the contents of the buffer without including messagesize back to the client, I'd say it was a fair assumption at the time.
    Since I'm finding the code very difficult to read and therefore have no intention of reading it, I won't argue with you there
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  13. #13
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    I'd agree with you on the readability of the code, it's not the best. From what I can tell it seems to be a mix of copy+paste from different tutorials and therefore coding styles without much re-formatting.

    >> Don't see what you mean... the code was in the first post he made.
    I meant that he didn't include the client side code or any sort of rough protocol spec. meaning it was impossible to know what data was being processed. This caused me to go on the only code which constructs a packet in his first post which doesn't include a message size. Looks like it was a bad assumption, but we should get on with helping our friend here Thanks for correcting my error.

    How's things going m1lk? Let us know -exactly- what you're after and what problems you're having and I'm more than willing to help, it's a tough subject. If you don't understand any of the tips anyone's given, you can always ask for it to be explained in more detail.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

  14. #14
    sockets mad
    Join Date
    Mar 2002
    Posts
    126
    Also, check out this post I made if you're looking to incorporate your send()s into your select() statement at some point.

    http://cboard.cprogramming.com/showt...592#post364592
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

    Come along and help make it a great resource for the community.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multiple clients to "internet" server
    By Zarniwoop in forum C Programming
    Replies: 2
    Last Post: 10-11-2008, 11:04 PM
  2. recieve data, then send data to all other clients
    By b00l34n in forum Networking/Device Communication
    Replies: 6
    Last Post: 07-25-2004, 11:13 AM
  3. Server Client Messaging Program
    By X PaYnE X in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-04-2004, 05:20 PM
  4. socket question
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 01:54 PM
  5. Replies: 2
    Last Post: 03-05-2002, 05:52 AM