Advertisement

Multiple Clients

Started by July 02, 2003 04:20 PM
3 comments, last by Jehsup 21 years, 7 months ago
hello, I have begun playing with sockets programming (UDP) in particular for my application that runs on 3 computers (all of which display an "out of the window" view, like you are flying an airplane and have 3 windows to look out of. Anyway, the little test server and client that I wrote (opposite in the traditiional sense I think) consist of the server which just pumps out application information (a structure) over the network to port 7000. My client picks it up fine, and everything works ok, but when I add an additional client (a clone of the first), it will not receive data until I close the first client down. I have read about broadcast and reusing addresses on MSDN, but I am apparently not understanding something correctly. My code below is for the simple server and client and my packet. The only code missing is my log generation class, and my simple vector class which has nothing to do with the server or client socket. Does anyone have an idea of what I need to do to make multiple clients receive from my server. SERVER CODE: // Standard Includes #include <iostream.h> #include "Packets.h" #include "log.h" #include "winsock2.h" void vServerConnection( int iListenPort ); void InitPacketValues( void ); void PrintDataReceived( void ); stHost_dataPacket DataPacket; int packetsize = 0; int errcode = 0; SOCKADDR_IN remote; SOCKET skSocket; int sentLen; int nPort = 7000; int done = 0; /////////////////////////////////////////// // ----> Main Program Function (REQUIRED) /////////////////////////////////////////// int main() { cout << "----------------------------------------------------" << endl; cout << " UDP Data Transmission_Receiving Test - S " << endl; cout << "----------------------------------------------------" << endl; cout << "" << endl; //initialize log file g_log.Init( "program_data.html" ); g_log.Write(LOG_PLAINTEXT,"Winsock UDP Server Starting..."); //init data packet values InitPacketValues(); //get packet information packetsize = sizeof(DataPacket); cout << "PacketSize(bytes): " << packetsize << endl; g_log.Write(LOG_RENDERER,"PacketSize(bytes): %d", packetsize); //set application as a server w\ given port number 7000 vServerConnection( nPort ); //cleanup sockets stuff errcode = WSACleanup(); if(errcode != 0) { cout << "Problem Closing Winsock socket!"<< endl; g_log.Write(LOG_FAILURE,"Winsock Cleanup Failed(ErrorCode): %i", (int)WSAGetLastError()); } else g_log.Write(LOG_RENDERER,"Successfully Cleaned Up Winsock Resources"); //exit return( -1 ); } // Function for server void vServerConnection( int iListenPort ) { int len = sizeof(SOCKADDR); char broadcast = 1; //initialize Winsock WSADATA data; errcode = WSAStartup(MAKEWORD(2,2), &data); if(errcode == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Could Not Init Winsock (ErrorCode): %i", (int)WSAGetLastError()); return; } else { g_log.Write(LOG_RENDERER, "Winsock Initialized..."); cout << "Winsock Initialized... " << endl; } //get a socket handle skSocket = socket(AF_INET, SOCK_DGRAM, 0); if(skSocket == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Could Not Create a Socket (ErrorCode): %i", (int)WSAGetLastError()); WSACleanup(); return; } else { g_log.Write(LOG_RENDERER, "Created a Valid Socket Handle..."); cout << "Got a Valid Socket handle" << endl; } //setup socket stuff remote.sin_family = AF_INET; remote.sin_addr.s_addr = inet_addr("127.0.0.1"); remote.sin_port = htons( iListenPort); //set socket options errcode = setsockopt(skSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(bool)); errcode = setsockopt(skSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&broadcast, sizeof(bool)); if(errcode == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Error Setting Socket Options(errorCode): %i", (int)WSAGetLastError()); cout << "Error Setting Options" << endl; } else { g_log.Write(LOG_RENDERER, "Set Socket for Broadcast receive"); cout << "Socket Broadcast Receiving" << endl; } //do our business here while(done != 1) { //send our packet sentLen = sendto(skSocket, (char*)&DataPacket, 156, 0, (SOCKADDR *)&remote, sizeof(SOCKADDR)); if(sentLen == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Error Sending Data (errorCode): %i", (int)WSAGetLastError()); } else { g_log.Write(LOG_RENDERER, "Sent Data(bytes): %d", sentLen); cout << "Sent Data (bytes): " << sentLen << endl; } } //close our socket closesocket(skSocket); } void InitPacketValues( void ) { DataPacket.frame = 0; DataPacket.quit = false; DataPacket.ACPos[0] = 449.8; DataPacket.ACPos[1] = 1.9; DataPacket.ACPos[2] = -8.2; DataPacket.ACrot[0] = 0.0; DataPacket.ACrot[1] = 45.4; DataPacket.ACrot[2] = 0.0; DataPacket.ACupvec[0] = 0.0; DataPacket.ACupvec[1] = 1.0; DataPacket.ACupvec[2] = 0.0; DataPacket.ACforwardvec[0] = 0.0; DataPacket.ACforwardvec[1] = 0.0; DataPacket.ACforwardvec[2] = -1.0; DataPacket.ACsidevec[0] = 1.0; DataPacket.ACsidevec[1] = 0.0; DataPacket.ACsidevec[2] = 0.0; DataPacket.AHstate[0] = false; DataPacket.AHstate[1] = false; DataPacket.AHstate[2] = false; DataPacket.AHstate[3] = false; DataPacket.AHstate[4] = false; DataPacket.AHpos[0] = 0.0; DataPacket.AHpos[1] = 0.0; DataPacket.AHpos[2] = 0.0; DataPacket.AHrot[0] = -6.0; DataPacket.AHrot[1] = 45.0; DataPacket.AHrot[2] = 0.0; DataPacket.ig_disable = false; DataPacket.isg_land_water = false; DataPacket.visibility = 60760.0; DataPacket.fog_disable = false; DataPacket.cloud_deck_top = 10000.0; DataPacket.cloud_deck_bottom = 10000.0; DataPacket.cloud_deck_depth = 0.0; DataPacket.cloud_deck_disable = false; DataPacket.time_of_day = 12.0; DataPacket.is_day = true; DataPacket.is_dusk = false; DataPacket.is_night = false; DataPacket.is_raining = false; DataPacket.is_snowing = false; DataPacket.is_lightning = false; DataPacket.VisualDatabase = 0; DataPacket.got_new_message = true; } void PrintDataReceived( void ) { //Format output of information for output to screen cout << " Data Received Frame = " << DataPacket.frame << endl; cout << " Data Received Quit = " << DataPacket.quit << endl; //position cout << " Data Received ACPosx= " << DataPacket.ACPos[0] << endl; cout << " Data Received ACPosy= " << DataPacket.ACPos[1] << endl; cout << " Data Received ACPosz= " << DataPacket.ACPos[2] << endl; //orientation cout << " Data Received ACrot Pitch= " << DataPacket.ACrot[0] << endl; cout << " Data Received ACrot Yaw= " << DataPacket.ACrot[1] << endl; cout << " Data Received ACrot Roll= " << DataPacket.ACrot[2] << endl; //vector orientation cout << " Data Received ACforwardvecX= " << DataPacket.ACforwardvec[0] << endl; cout << " Data Received ACforwardvecY= " << DataPacket.ACforwardvec[1] << endl; cout << " Data Received ACforwardvecZ= " << DataPacket.ACforwardvec[2] << endl; cout << " Data Received ACsidevecX= " << DataPacket.ACsidevec[0] << endl; cout << " Data Received ACsidevecY= " << DataPacket.ACsidevec[1] << endl; cout << " Data Received ACsidevecZ= " << DataPacket.ACsidevec[2] << endl; cout << " Data Received ACupvecX= " << DataPacket.ACupvec[0] << endl; cout << " Data Received ACupvecY= " << DataPacket.ACupvec[1] << endl; cout << " Data Received ACupvecZ= " << DataPacket.ACupvec[2] << endl; //hazard data cout << " Data Received AHstate0= " << DataPacket.AHstate[0] << endl; cout << " Data Received AHstate1= " << DataPacket.AHstate[1] << endl; cout << " Data Received AHstate2= " << DataPacket.AHstate[2] << endl; cout << " Data Received AHstate3= " << DataPacket.AHstate[3] << endl; cout << " Data Received AHstate4= " << DataPacket.AHstate[4] << endl; //position cout << " Data Received AHposX= " << DataPacket.AHpos[0] << endl; cout << " Data Received AHposY= " << DataPacket.AHpos[1] << endl; cout << " Data Received AHposZ= " << DataPacket.AHpos[2] << endl; //orientation cout << " Data Received AHrotX= " << DataPacket.AHrot[0] << endl; cout << " Data Received AHrotY= " << DataPacket.AHrot[1] << endl; cout << " Data Received AHrotZ= " << DataPacket.AHrot[2] << endl; //IG cout << " Data Received IGstate= " << DataPacket.ig_disable << endl; cout << " Data Received ISGTexturestate= " << DataPacket.isg_land_water << endl; //fog cout << " Data Received Visibility= " << DataPacket.visibility << endl; cout << " Data Received FogDisable= " << DataPacket.fog_disable << endl; //clouds cout << " Data Received CDt= " << DataPacket.cloud_deck_top << endl; cout << " Data Received CDb= " << DataPacket.cloud_deck_bottom << endl; cout << " Data Received CDd= " << DataPacket.cloud_deck_depth << endl; cout << " Data Received CDs= " << DataPacket.cloud_deck_disable << endl; //time of day cout << " Data Received TOD= " << DataPacket.time_of_day << endl; cout << " Data Received TODd= " << DataPacket.is_day << endl; cout << " Data Received TODdsk= " << DataPacket.is_dusk << endl; cout << " Data Received TODn= " << DataPacket.is_night << endl; //particles cout << " Data Received Rain= " << DataPacket.is_raining << endl; cout << " Data Received Snow= " << DataPacket.is_snowing << endl; cout << " Data Received Lightning= " << DataPacket.is_lightning << endl; //requested database model cout << " Data Received Requested DB= " << DataPacket.VisualDatabase << endl; //message flag cout << " Data Received New Message Booleon = " << DataPacket.got_new_message << endl; } CLIENT CODE: // Standard Includes #include <iostream.h> #include "Packets.h" #include "log.h" #include "winsock2.h" //function prototypes //void vClientConnection( char *szServerIP, int iServerListenPort ); void vClientConnection(int iServerListenPort ); void PrintDataReceived( void ); void InitPacketValuesClient( void ); //variables stHost_dataPacket DataPacket; int packetsize = 0; int number = 0; int done = 0; SOCKADDR_IN saServer; SOCKADDR from; SOCKET skSocket; int gotLen; int nPort = 7000; int errcode; //////////////////////////////////////////////// // ----> Main Program Function (REQUIRED) //////////////////////////////////////////////// int main() { char * IPaddr = "192.168.1.104";//my computer''s IP address cout << "----------------------------------------------------" << endl; cout << " UDP Data Receiving Test - CLIENT " << endl; cout << "----------------------------------------------------" << endl; cout << "" << endl; //initialize log file g_log.Init( "program_data.html" ); g_log.Write(LOG_PLAINTEXT,"Winsock UDP Client Starting..."); //initialize the packet values InitPacketValuesClient(); //check and print the packet size packetsize = sizeof(DataPacket); cout << "PacketSize(bytes): " << packetsize << endl; g_log.Write(LOG_RENDERER, "PacketSize(bytes) : %d", packetsize); //establish client connection to given IP and port //vClientConnection( IPaddr, 7000 ); vClientConnection( nPort ); //cleanup Winsock WSACleanup(); g_log.Write(LOG_RENDERER, "Cleaned Up Winsock Resources"); return( -1 ); } // Function for client //void vClientConnection( char *szServerIP, int iServerListenPort ) void vClientConnection(int iServerListenPort ) { WSADATA data; int len = sizeof(SOCKADDR); char broadcast = 1; //intialize Winsock errcode = WSAStartup(MAKEWORD(2,2), &data); if(errcode == SOCKET_ERROR) { cout << "Error Initializing Winsock" << endl; g_log.Write(LOG_FAILURE,"Error Initializing Winsock(ErrorCode): %i", (int)WSAGetLastError()); WSACleanup(); return; } else { cout << "Initializing Winsock" << endl; g_log.Write(LOG_RENDERER,"Initializing Winsock"); } //get a socket handle skSocket = socket(AF_INET, SOCK_DGRAM, 0); if(skSocket == SOCKET_ERROR) { cout << "Could Not Get a Valid Socket Handle" << endl; g_log.Write(LOG_FAILURE,"Could Not Get Valid Socket Handle(ErrorCode): %i", (int)WSAGetLastError()); WSACleanup(); return; } else { cout << "Got a valid socket handle" << endl; g_log.Write(LOG_RENDERER,"Got a valid socket handle"); } //setup some sockets stuff saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = INADDR_ANY; saServer.sin_port = htons(iServerListenPort); //set socket options errcode = setsockopt(skSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(bool)); errcode = setsockopt(skSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&broadcast, sizeof(bool)); if(errcode == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Error Setting Socket Options(errorCode): %i", (int)WSAGetLastError()); cout << "Error Setting Options" << endl; } else { g_log.Write(LOG_RENDERER, "Set Socket for Broadcast receive"); cout << "Socket Broadcast Receiving" << endl; } //bind the socket errcode = bind(skSocket, (SOCKADDR *)&saServer, sizeof(SOCKADDR)); if(errcode == SOCKET_ERROR) { g_log.Write(LOG_FAILURE, "Error Binding Socket(errorCode): %i", (int)WSAGetLastError()); cout << "Error Binding Socket" << endl; } else { g_log.Write(LOG_RENDERER, "Bound Socket"); cout << "Socket Bound" << endl; } //show what port we are using g_log.Write(LOG_RENDERER, "Using Port: %d", iServerListenPort); cout << "Using Port: " << iServerListenPort << endl; while(done != 1) { gotLen = recvfrom(skSocket, (char *)&DataPacket, 156, 0, &from, &len); if(gotLen == SOCKET_ERROR) { cout << "Error Receving Data" << endl; g_log.Write(LOG_FAILURE,"Error Receiving Data(ErrorCode): %i", (int)WSAGetLastError()); } else { cout << "Got Packet(bytes): " << gotLen < Data Received Frame = " << DataPacket.frame << endl; cout << " Data Received Quit = " << DataPacket.quit << endl; //position cout << " Data Received ACPosx= " << DataPacket.ACPos[0] << endl; cout << " Data Received ACPosy= " << DataPacket.ACPos[1] << endl; cout << " Data Received ACPosz= " << DataPacket.ACPos[2] << endl; //orientation cout << " Data Received ACrot Pitch= " << DataPacket.ACrot[0] << endl; cout << " Data Received ACrot Yaw= " << DataPacket.ACrot[1] << endl; cout << " Data Received ACrot Roll= " << DataPacket.ACrot[2] << endl; //vector orientation cout << " Data Received ACforwardvecX= " << DataPacket.ACforwardvec[0] << endl; cout << " Data Received ACforwardvecY= " << DataPacket.ACforwardvec[1] << endl; cout << " Data Received ACforwardvecZ= " << DataPacket.ACforwardvec[2] << endl; cout << " Data Received ACsidevecX= " << DataPacket.ACsidevec[0] << endl; cout << " Data Received ACsidevecY= " << DataPacket.ACsidevec[1] << endl; cout << " Data Received ACsidevecZ= " << DataPacket.ACsidevec[2] << endl; cout << " Data Received ACupvecX= " << DataPacket.ACupvec[0] << endl; cout << " Data Received ACupvecY= " << DataPacket.ACupvec[1] << endl; cout << " Data Received ACupvecZ= " << DataPacket.ACupvec[2] << endl; //hazard data cout << " Data Received AHstate0= " << DataPacket.AHstate[0] << endl; cout << " Data Received AHstate1= " << DataPacket.AHstate[1] << endl; cout << " Data Received AHstate2= " << DataPacket.AHstate[2] << endl; cout << " Data Received AHstate3= " << DataPacket.AHstate[3] << endl; cout << " Data Received AHstate4= " << DataPacket.AHstate[4] << endl; //position cout << " Data Received AHposX= " << DataPacket.AHpos[0] << endl; cout << " Data Received AHposY= " << DataPacket.AHpos[1] << endl; cout << " Data Received AHposZ= " << DataPacket.AHpos[2] << endl; //orientation cout << " Data Received AHrotX= " << DataPacket.AHrot[0] << endl; cout << " Data Received AHrotY= " << DataPacket.AHrot[1] << endl; cout << " Data Received AHrotZ= " << DataPacket.AHrot[2] << endl; //IG cout << " Data Received IGstate= " << DataPacket.ig_disable << endl; cout << " Data Received ISGTexturestate= " << DataPacket.isg_land_water << endl; //fog cout << " Data Received Visibility= " << DataPacket.visibility << endl; cout << " Data Received FogDisable= " << DataPacket.fog_disable << endl; //clouds cout << " Data Received CDt= " << DataPacket.cloud_deck_top << endl; cout << " Data Received CDb= " << DataPacket.cloud_deck_bottom << endl; cout << " Data Received CDd= " << DataPacket.cloud_deck_depth << endl; cout << " Data Received CDs= " << DataPacket.cloud_deck_disable << endl; //time of day cout << " Data Received TOD= " << DataPacket.time_of_day << endl; cout << " Data Received TODd= " << DataPacket.is_day << endl; cout << " Data Received TODdsk= " << DataPacket.is_dusk << endl; cout << " Data Received TODn= " << DataPacket.is_night << endl; //particles cout << " Data Received Rain= " << DataPacket.is_raining << endl; cout << " Data Received Snow= " << DataPacket.is_snowing << endl; cout << " Data Received Lightning= " << DataPacket.is_lightning << endl; //requested database model cout << " Data Received Requested DB= " << DataPacket.VisualDatabase << endl; //message flag cout << " Data Received New Message Booleon = " << DataPacket.got_new_message << endl; } MY PACKET(in PACKETS.H file): #include "vector.h" #define PACKET_HOST_DATA 1 //uses all existing host_data struct stHost_dataPacket { int frame; bool quit; //aircraft data CVECTOR ACPos; CVECTOR ACrot; CVECTOR ACupvec; CVECTOR ACforwardvec; CVECTOR ACsidevec; float movementSpeed; //air hazard data bool AHstate[5]; CVECTOR AHpos; CVECTOR AHrot; int AHindex; //infinite ground\sky stuff bool ig_disable; bool isg_land_water; //fog float visibility; bool fog_disable; //clouds float cloud_deck_top; float cloud_deck_bottom; float cloud_deck_depth; bool cloud_deck_disable; //time of day float time_of_day; bool is_day; bool is_dusk; bool is_night; //particles bool is_raining; bool is_snowing; bool is_lightning; //database int VisualDatabase; bool got_new_message; }; Thanks in advance for any ideas you can give. Jehsup
You are using a broadcast socket... you need to sendto() to a broadcast address.
Advertisement
Thanks for the info, but could you be more specific? I''m just getting started, and I''m not sure exactly what you mean.

Thanks,
J
Thanks again, fingh. You lead me down the right path and i figured it out.

I made the server
remote.sin_addr.s_addr = htonl(INADDR_BROADCAST);

INSTEAD OF:
remote.sin_addr.s_addr = inet_addr("127.0.0.1");

and it works great now.

J
quote:
Original post by Jehsup
Thanks again, fingh. You lead me down the right path and i figured it out.


Yeah, sorry about the lack of details in the original post. There are all different levels of programmers here, so it''s hard to know when to go into detail. I''m glad you were able to find the solution.

This topic is closed to new replies.

Advertisement