C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 09-22-2004, 08:27 PM   #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
mill1k is offline   Reply With Quote
Old 09-23-2004, 12:25 PM   #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.
codec is offline   Reply With Quote
Old 09-23-2004, 12:32 PM   #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)
__________________
C/C++ Support IRC Channel

Server: irc.dal.net Channel: #csupport

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

Last edited by codec; 09-23-2004 at 12:34 PM.
codec is offline   Reply With Quote
Old 09-23-2004, 04:26 PM   #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
mill1k is offline   Reply With Quote
Old 09-23-2004, 05:22 PM   #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?
__________________
C/C++ Support IRC Channel

Server: irc.dal.net Channel: #csupport

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

Last edited by codec; 09-23-2004 at 05:44 PM.
codec is offline   Reply With Quote
Old 09-26-2004, 12:40 PM   #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
mill1k is offline   Reply With Quote
Old 09-26-2004, 07:44 PM   #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.
mill1k is offline   Reply With Quote
Old 09-27-2004, 05:19 AM   #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.
codec is offline   Reply With Quote
Old 09-28-2004, 09:33 AM   #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.
__________________
C/C++ Support IRC Channel

Server: irc.dal.net Channel: #csupport

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

Last edited by codec; 09-28-2004 at 09:38 AM.
codec is offline   Reply With Quote
Old 09-29-2004, 07:26 PM   #10
Carnivore ('-'v)
 
Hunter2's Avatar
 
Join Date: May 2002
Posts: 2,866
>>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.
Hunter2 is offline   Reply With Quote
Old 09-30-2004, 08:07 AM   #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.
__________________
C/C++ Support IRC Channel

Server: irc.dal.net Channel: #csupport

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

Last edited by codec; 09-30-2004 at 08:31 AM.
codec is offline   Reply With Quote
Old 09-30-2004, 10:24 AM   #12
Carnivore ('-'v)
 
Hunter2's Avatar
 
Join Date: May 2002
Posts: 2,866
>>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.

Quote:
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.
Hunter2 is offline   Reply With Quote
Old 09-30-2004, 12:20 PM   #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.
codec is offline   Reply With Quote
Old 09-30-2004, 12:23 PM   #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.
codec is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Multiple clients to "internet" server Zarniwoop C Programming 2 10-11-2008 11:04 PM
recieve data, then send data to all other clients b00l34n Networking/Device Communication 6 07-25-2004 11:13 AM
Server Client Messaging Program X PaYnE X Networking/Device Communication 3 01-04-2004 05:20 PM
socket question Unregistered C Programming 3 07-19-2002 01:54 PM
More Winsock threads: Proper way to recv() and send() to multiple clients Unregistered Windows Programming 2 03-05-2002 05:52 AM


All times are GMT -6. The time now is 06:56 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22