Reputation: 2754
I have created single Server and Single Client echo application. It works fine for single server and single client. But now I want to make it more practical by handling multiple clients for a single Server. I came accross the idea of using listen() function at Server side to handle multiple client connections but then I came to know that listen is only used for TCP. Kindly help me with this. below is my functional code for single Server and Single Client. Help me with how can I modify it to make a Single Server Multiple Client application.
SERVER:
#define PORT 8888 //The port on which to listen for incoming data
int main()
{
SOCKET s;
struct sockaddr_in serverSocket, clientSocket;
char receiveBuffer[1000];
//int receiveBufferLength=1000;
int clientSocketLength;
int recv_len;
clientSocketLength = sizeof(clientSocket) ;
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Socket Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
serverSocket.sin_family = AF_INET;
serverSocket.sin_addr.s_addr = INADDR_ANY;
serverSocket.sin_port = htons( PORT );
//Bind
if( bind(s ,(struct sockaddr *)&serverSocket , sizeof(serverSocket)) == SOCKET_ERROR)
{
printf("\nBind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Bind done\n\n");
//keep listening for data
while(1)
{
printf("\n\t\t\tWaiting for data...\n");
fflush(stdout);
//receiveBuffer[2000]=NULL;
if((recv_len = recvfrom(s, receiveBuffer, 1000, 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
{
printf("\n\nrecvfrom() failed with error code : %d" , WSAGetLastError());
//exit(EXIT_FAILURE);
while(1);
}
//print details of the client/peer and the data received
printf("\n\nReceived packet from %s:%d\n", inet_ntoa(clientSocket.sin_addr), ntohs(clientSocket.sin_port));
printf("\nClient Says: " );
printf(receiveBuffer,recv_len);
//now reply the client with the same data
if (sendto(s, receiveBuffer, recv_len, 0, (struct sockaddr*) &clientSocket, clientSocketLength) == SOCKET_ERROR)
{
printf("\nsendto() failed with error code : %d" , WSAGetLastError());
// exit(EXIT_FAILURE);
while(1);
}
else
printf("\nMessage Sent Back to Client");
}
closesocket(s);
WSACleanup();
return 0;
}
CLIENT:
#define PORT 8888 //The port on which to listen for incoming data
#define SERVER "10.0.1.25" //ip address of udp server
//#define PORT 8888 //The port on which to listen for incoming data
int main(void)
{
struct sockaddr_in connectedSocket;
int s;
int length=sizeof(connectedSocket);
char receiveBuffer[1000];
char message[1000];
//clear the buffer by filling null, it might have previously received data
memset(receiveBuffer,'\0', 1000);
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...\n");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("\nFailed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\n.........Initialised.\n");
//create socket
if ( (s=socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR)
{
printf("\n\nsocket() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *) &connectedSocket, 0, sizeof(connectedSocket));
connectedSocket.sin_family = AF_INET;
connectedSocket.sin_port = htons(PORT);
//connectedSocket.sin_port = INADDR_BROADCAST;
connectedSocket.sin_addr.S_un.S_addr = inet_addr(SERVER);
while(1)
{
printf("\n\n\nEnter message : ");
gets(message);
//send the message
if (sendto(s, message,sizeof(message) , 0 , (struct sockaddr *) &connectedSocket, sizeof(connectedSocket)) == SOCKET_ERROR)
{
printf("\nsendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\nMessage Successfully sent to Server");
// fflush(stdout);
if (recvfrom(s, receiveBuffer, 1000, 0, (struct sockaddr *) &connectedSocket,&length) == SOCKET_ERROR)
{
printf("\nrecvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\nServer Says : ");
printf(receiveBuffer,sizeof(receiveBuffer));
}
closesocket(s);
WSACleanup();
return 0;
}
Upvotes: 0
Views: 7134
Reputation: 375
Let me explain a few things for you that might be confusing.
First, in your server you need to set serverSocket.sin_addr.s_addr
to INADDR_ANY
even if you want to broadcast. You don't want to make it INADDR_BROADCAST
. This is simply telling the server to bind on any IP address your computer has, cause a single computer can have more than 1 IP. Which you are doing correctly.
But how can you broadcast from the server? You need to use setsockopt
with SO_BROADCAST
parameter like this ...
int options = 1;
if ((setsockopt(s, SOL_SOCKET, SO_BROADCAST,(char *)&options,sizeof(options))) < 0){
printf("%d",WSAGetLastError());
}
This will make your server listens for broadcasts, but how can you send broadcasts? You need to set INADDR_BROADCAST
in the s_addr
field in the sockaddr structure before calling sendto
function.
clientSocket.sin_addr.s_addr = INADDR_BROADCAST;
Then use sendto
with clientSocket
to boardcast your messsage back.
Second, in your client code, you have two options depending on your application.
If you want your clients to send message first to the server (direct without broadcast) then you are doing it right, by setting inet_addr(SERVER)
so the client send the message to your server only.
But, if you want the client to broadcast the message, then you need to use setsockopt
again in your client, same as in your server, and set the address in connectSocket
structure to INADDR_BROADCAST
.
Finally, it would be better if you tell us what are you trying to accomplish here. If you want clients to connect to server first, then the server announce the client to other clients, then you might take TCP instead of UDP.
Upvotes: 2