Multiple Clients
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.
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,
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
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
Popular Topics
Advertisement
Recommended Tutorials
Advertisement