Client unable to receive messages from BROADCAST UDP Server. (Winsock) - winapi

I have developed a client server UDP application. The Server UDP socket is set to be a BROADCAST UDP Socket. The code of both sides does not generate any error, but the message sent from BROADCAST UDP SERVER Side is not Received at client side. Kindly have a look at my code, i know there is some blunder I can't figure out. I really need help:
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 );
int broadcast =1;
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*) &broadcast, sizeof(broadcast)) < 0) {
//close(sock);
printf("Error in setting broadcast option");
}
//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
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);
serverSocket.sin_addr.s_addr = INADDR_BROADCAST;
//now reply the client with the same data
if (sendto(s, receiveBuffer, recv_len, 0, (struct sockaddr*) &serverSocket, sizeof(serverSocket)) == SOCKET_ERROR)
{
printf("\nsendto() failed with error code : %d" , WSAGetLastError());
// exit(EXIT_FAILURE);
while(1);
}
else
printf("\nMessage Sent Back to Client");
while(1);
closesocket(s);
WSACleanup();
return 0;
}
CLIENT:
#define PORT 8888 //The port on which to listen for incoming data
#define SERVER "127.0.0.1" //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);
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);
while(1);
}
printf("\nServer Says : ");
printf(receiveBuffer,sizeof(receiveBuffer));
while(1);
closesocket(s);
WSACleanup();
return 0;
}

You are sending the reply back to the client on the serverSocket. You already have a clientsocket that you received the message on, use it to send the message back from the server to the client.
Remove ...
serverSocket.sin_addr.s_addr = INADDR_BROADCAST;
and change ...
if (sendto(s, receiveBuffer, recv_len, 0, (struct sockaddr*) &serverSocket, sizeof(serverSocket)) == SOCKET_ERROR)
to
if (sendto(s, receiveBuffer, recv_len, 0, (struct sockaddr*) &clientSocket, sizeof(clientSocket)) == SOCKET_ERROR)
It should work now.

Related

Winsock "recv" doesn't return on a non-graceful connection termination

I'm running the following code:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "8081"
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo* result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
while (true)
{
printf("Waiting for connection...\n");
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("Received connection !\n");
}
// No longer need server socket
//closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do {
printf("Before recv\n");
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
printf("After recv\n");
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
recvbuf[iResult] = 0;
// Echo the buffer back to the sender
printf("%s\n", recvbuf);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
printf("After loop !!\n");
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
//
}
// shutdown the connection since we're done
WSACleanup();
return 0;
}
When a client terminates the connection ungracefully, i.e., just shuts down without calling close() or anything, the recv() function is blocking and doesn't return.
I've read in the docs of the recv function that:
If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.
But that's not the case. In my case, the recv() just blocks the execution. I guess that the docs refer to a situation in which you call recv() AFTER the connection has been closed by the peer, but in my case, the connection is being closed after recv() was called.
How can I handle this?
An abnormal connection loss (where network communication just stops, vs a reset which is explicit) takes time for the OS to detect it. TCP is designed to be resilient in case of a network outage. recv() WILL fail eventually, but it could take up to several minutes for the OS to timeout internally and invalidate the connection. Until that happens, no errors are reported.
If you don't want to wait the necessary time for the OS to invalidate the connection, you will have to enable use of your own timeout in your own code, such as by calling select() before recv(), or by using setsockopt(SO_RCVTIMEO), WSAIoctl(SIO_KEEPALIVE_VALS), etc to make recv() exit on a timeout. Then you can close the socket if the timeout elapses.

Socket Programming on Visual C++: recv() returns error code 10053 and 10014 in my TCP Echo Server-Client

Can anyone please point out the error in my code?
I already have previous knowledge about socket programming in Linux using C. So, I tried writing a simple TCP echo server and client program using Visual C++ on Visual Studio 2017 in my Windows 8.1 machine.
I am able to send any message to the server or the client can send any message to any server using the send() function. But I cannot receive any message using the recv() method. On the server the recv() function returns the error code 10053 and the client returns an error code 10014. Below are the source codes of the programs.
tcpServer.cpp
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char **argv) {
WSADATA wsa;
SOCKET s, cs;
struct sockaddr_in server_addr, client_addr;
unsigned short server_port = 4444;
char* server_ip = "192.168.2.5";
int client_addr_len;
char *message = "Hello World";
int r;
/*if (argc < 2) {
printf("usage: tcpServer.exe <your IP address>");
exit(1);
}
strcpy_s(server_ip, argv[1]);*/
//Display stuff
system("cls");
printf("\t\tTCP ECHO SERVER\n\n");
printf("Creating TCP echo server on the IP %s\n", server_ip);
//Initialise WinSock
printf("Initialising WinSock....\n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("ERROR: Initialising failed with error Code : %d", WSAGetLastError());
exit(1);
}
printf("Successfully initialised.\n");
//Create socket
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("ERROR: Socket creating failed with error code: %d", WSAGetLastError());
exit(1);
}
printf("Socket created successfully.\n");
//Setting the struct sockaddr_in server_addr
server_addr.sin_addr.s_addr = inet_addr(server_ip);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
//Binding
if (bind(s, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
printf("ERROR: Could not bind to port with error code: %d", WSAGetLastError());
exit(1);
}
printf("Bound to port %d\n", server_port);
//Start listening for client
printf("\nListening for client connections on %s:%d\n", server_ip, server_port);
if (listen(s, 5) < 0) {
printf("ERROR: Cannot listen for client connections with error code: %d", WSAGetLastError());
exit(1);
}
//Accepting connections
client_addr_len = sizeof(struct sockaddr_in);
if ((cs = accept(s, (struct sockaddr*)&client_addr, &client_addr_len)) == INVALID_SOCKET) {
printf("ERROR: Cannot accept connections with error code: %d", WSAGetLastError());
exit(1);
}
printf("Connection accepted from %s\n", inet_ntoa(client_addr.sin_addr));
//No need of SOCKET s
closesocket(s);
//Receive messages
if ((r = recv(cs, message, 2000, 0)) < 0) {
printf("ERROR: Cannot receive messages with error code: %d", WSAGetLastError());
exit(1);
}
message = "Hello World";
printf("Message received: %s\n", message);
//Send back the message
send(cs, message, strlen(message), 0);
printf("Message echoed back to server: %s\n", message);
//Close and clearing
closesocket(cs);
WSACleanup();
}
tcpClient.cpp
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char **argv) {
WSADATA wsa;
SOCKET s, cs;
struct sockaddr_in server_addr, client_addr;
unsigned short server_port = 4444;
char* server_ip = "192.168.2.5";
int client_addr_len;
char *message = "Hello World";
int r;
system("cls");
printf("\t\tTCP ECHO CLIENT\n\n");
printf("Connecting to TCP echo server on the IP %s\n", server_ip);
printf("Initialising WinSock....\n");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("ERROR: Initialising failed with error Code : %d", WSAGetLastError());
exit(1);
}
printf("Successfully initialised.\n");
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("ERROR: Socket creating failed with error code: %d", WSAGetLastError());
exit(1);
}
printf("Socket created successfully.\n");
server_addr.sin_addr.s_addr = inet_addr(server_ip);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
if (connect(s, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
printf("ERROR: Cannot connect to server %s", server_ip);
closesocket(s);
exit(1);
}
printf("Connected to server %s on port %d\n", server_ip, server_port);
if (send(s, message, strlen(message), 0) < 0) {
printf("ERROR: Message sending failed with error code %d", WSAGetLastError());
closesocket(s);
exit(1);
}
printf("Message sending was successful\n");
if (recv(s, message, 2000, 0) < 0) {
printf("ERROR: Message recieving failed with error code %d", WSAGetLastError());
closesocket(s);
exit(1);
}
printf("Message echoed back from server: %s\n", message);
getchar();
closesocket(s);
WSACleanup();
}
Outputs
On both sides, message is just a pointer, and you have it pointing at a read-only string literal. recv() is trying to read data into that literal's memory, which will fail. You need to change message to a fixed-sized array instead:
//char *message = "Hello World";
char message[2000];
On the server side, you are making a similar mistake with your server_ip value (if you uncomment the call to strcpy_n()).
Also, when calling recv(), you are ignoring its return value. You only check it for -1 (read error), but it can also return 0 (graceful disconnect) or > 0 (data received). The data is not null-terminated! You must take the actual number of bytes read into account when calling printf() afterwards. Don't use strlen(), unless you null-terminate the data manually.
Try something more like this instead:
Server
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char **argv) {
WSADATA wsa;
SOCKET s = INVALID_SOCKET, cs = INVALID_SOCKET;
struct sockaddr_in server_addr, client_addr;
unsigned short server_port = 4444;
char* server_ip;
int client_addr_len;
char message[2000];
int r, exitCode = 1;
/*if (argc < 2) {
printf("usage: tcpServer.exe <your IP address>");
exit(1);
}
server_ip = argv[1];
*/
server_ip = "192.168.2.5";
//Display stuff
system("cls");
printf("\t\tTCP ECHO SERVER\n\n");
printf("Creating TCP echo server on the IP %s\n", server_ip);
//Initialise WinSock
printf("Initialising WinSock....\n");
if ((r = WSAStartup(MAKEWORD(2, 2), &wsa)) != 0) {
printf("ERROR: Initialising failed with error Code : %d", r);
exit(1);
}
printf("Successfully initialised.\n");
//Create socket
if ((s = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET) {
printf("ERROR: Socket creating failed with error code: %d", WSAGetLastError());
goto cleanup;
}
printf("Socket created successfully.\n");
//Setting the struct sockaddr_in server_addr
server_addr.sin_addr.s_addr = inet_addr(server_ip);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
//Binding
if (bind(s, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
printf("ERROR: Could not bind to port with error code: %d", WSAGetLastError());
goto cleanup;
}
printf("Bound to port %d\n", server_port);
//Start listening for client
printf("\nListening for client connection on %s:%d\n", server_ip, server_port);
if (listen(s, 1) == SOCKET_ERROR) {
printf("ERROR: Cannot listen for client connection with error code: %d", WSAGetLastError());
goto cleanup;
}
//Accepting connection
client_addr_len = sizeof(client_addr);
if ((cs = accept(s, (struct sockaddr*)&client_addr, &client_addr_len)) == INVALID_SOCKET) {
printf("ERROR: Cannot accept connection with error code: %d", WSAGetLastError());
goto cleanup;
}
printf("Connection accepted from %s\n", inet_ntoa(client_addr.sin_addr));
//No need of SOCKET s anymore
closesocket(s);
s = INVALID_SOCKET;
//Receive messages
if ((r = recv(cs, message, 2000, 0)) == SOCKET_ERROR) {
printf("ERROR: Cannot receive message with error code: %d", WSAGetLastError());
goto cleanup;
}
if (r == 0) {
printf("Client disconnected");
goto cleanup;
}
printf("Message received: %.*s\n", r, message);
//Send back the message
if (send(cs, message, r, 0) == SOCKET_ERROR) {
printf("ERROR: Cannot send message with error code: %d", WSAGetLastError());
goto cleanup;
}
printf("Message echoed back to client: %.*s\n", r, message);
exitCode = 0;
cleanup:
//Close and clearing
if (cs != INVALID_SOCKET) closesocket(cs);
if (s != INVALID_SOCKET) closesocket(s);
WSACleanup();
return exitCode;
}
Client
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char **argv) {
WSADATA wsa;
SOCKET s = INVALID_SOCKET;
struct sockaddr_in server_addr, client_addr;
unsigned short server_port = 4444;
char* server_ip = "192.168.2.5";
int client_addr_len;
char message[2000];
int r, exitCode = 1;
system("cls");
printf("\t\tTCP ECHO CLIENT\n\n");
printf("Connecting to TCP echo server on the IP %s\n", server_ip);
printf("Initialising WinSock....\n");
if ((r = WSAStartup(MAKEWORD(2, 2), &wsa)) != 0) {
printf("ERROR: Initialising failed with error Code : %d", r);
exit(1);
}
printf("Successfully initialised.\n");
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("ERROR: Socket creating failed with error code: %d", WSAGetLastError());
goto cleanup;
}
printf("Socket created successfully.\n");
server_addr.sin_addr.s_addr = inet_addr(server_ip);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
if (connect(s, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
printf("ERROR: Cannot connect to server %s", server_ip);
goto cleanup;
}
printf("Connected to server %s on port %d\n", server_ip, server_port);
strcpy_s(message, sizeof(message), "Hello World");
if (send(s, message, strlen(message), 0) == SOCKET_ERROR) {
printf("ERROR: Message sending failed with error code %d", WSAGetLastError());
goto cleanup;
}
printf("Message sending was successful\n");
if ((r = recv(s, message, sizeof(message), 0)) == SOCKET_ERROR) {
printf("ERROR: Message receiving failed with error code %d", WSAGetLastError());
goto cleanup;
}
if (r == 0) {
printf("Server disconnected");
goto cleanup;
}
printf("Message echoed back from server: %.*s\n", r, message);
getchar();
exitCode = 0;
cleanup:
if (s != INVALID_SOCKET) closesocket(s);
WSACleanup();
return exitCode;
}
That being said, on the server side, when calling listen(), there is no point in setting the backlog to 5 if you are only ever going to accept 1 client. If you really want to implement a useful server, you should be calling accept() in a loop instead for the lifetime of the server, using select() or worker threads to monitor connected clients.

Single Server, Multiple Clients UDP Application in C (Winsock)

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;
}
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 connectSocketstructure 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.

Sockets - sending image

fp = fopen("image.jpg","rb");
if (!fp)
exit(1);
fseek(fp,0,SEEK_END);
len = ftell(fp);
fseek(fp,0,SEEK_SET);
buf = (char *)malloc(len);
fread(buf,len,1,fp);
fclose(fp);
if (WSAStartup(0x0202,&wsa) != 0)
{
printf("Error code : %d",WSAGetLastError());
return 1;
}
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Error code : %d" , WSAGetLastError());
WSACleanup();
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Error code : %d" , WSAGetLastError());
closesocket(s);
WSACleanup();
exit(EXIT_FAILURE);
}
sprintf(str,"%d",len);
strcpy(message,"HTTP/1.1 200 OK\r\nContent-Length: ");
sprintf(message,"%s %s",message,str);
sprintf(message,"%s %s",message,"\r\nContent-Type: image/jpeg\r\n\r\n");
sprintf(message,"%s %s",message,buf);
sprintf(message,"%s %s",message,"\r\n");
listen(s , 100);
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(s , (struct sockaddr *)&client, &c)) != INVALID_SOCKET )
{
memset(recvdata,'\0',sizeof(recvdata));
recv(new_socket,recvdata,2000,0);
send(new_socket , message , strlen(message) , 0);
}
if (new_socket == INVALID_SOCKET)
{
printf("Error code : %d" , WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
I have a problem with sending image file. This is server side of communication and browser will be client side. When i try to connect to server, server accepts connection and everything is ok. Then i want to send image as response, and it should be showed in browser. Can anyone tell me what is a problem here?
Many issues. Just to start:
You are not checking return values of system calls (listen(), recv(), send(), etc.), so you don't know about errors, and how much data you sent or received.
Printing binary data like from image file here with printf() is a Bad IdeaTM - it will be truncated at the first zero byte, or it might overrun your memory with a lack of such.
You are assuming recv() consumes full HTTP request from a client. It might not, so you are breaking HTTP protocol.
You are not closing connected client socket in your loop. That is a resource leak.

UDP socket programming in windows

I developed code to receive udp packets from the port. But after calling recvfrom() nothing is happening. Following is my code and output.
#include "udpSocket.h"
int main(void)
{
SOCKET sockID;
WSADATA wsaData = {0};
FILE *udp;
char buf[512];
static int recvData;
int iResult = 0;
int sock_len = sizeof(fepAddr);
int recvResult;
int seqNo = 0;
static int outOfSeqCnt = 0;
FILE *fp = fopen("outOfSeq.txt","a");
if((udp = fopen("udpData.txt","w")) == 0)
printf("udpData.txt not opened\n");
printf("\n-------------------------------------\n");
printf("\tUDP Packet Receiver\n");
printf("-------------------------------------\n");
printf("\n Enter Destination FEP IP Address : ");
scanf_s("%s",inputData.destIPAddr,16);
printf("\n Enter Destination port from which to receive data : ");
scanf_s("%d",&inputData.portNo,5);
printf("\n Enter No.of iterations : ");
scanf_s("%d",&inputData.noIteration,2);
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(iResult < 0)
{
printf("windows socket startup error\n");
}
sockID = socket(PF_INET, SOCK_DGRAM, 0);
if(sockID < 0)
{
printf("Socket creation error\n");
WSACleanup();
}
else
{
printf("Socket Created\n");
}
fepAddr.sin_family = AF_INET;
fepAddr.sin_port = htons(inputData.portNo);
//fepAddr.sin_addr.s_addr = inet_addr(inputData.destIPAddr);
fepAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockID, (struct sockaddr *)&fepAddr, sizeof(struct sockaddr)) < 0)
{
printf("bind() failed: %ld.\n", WSAGetLastError());
closesocket(sockID);
return 0;
}
else
{
printf("bind() is OK!\n");
}
memset(udpBuf, 0, sizeof(udpBuf));
recvData = 1;
while (recvData)
{
printf("receiving data\n");
recvResult = recvfrom(sockID, udpBuf, sizeof(udpBuf), 0,(struct sockaddr *)&fepAddr, &sock_len);
if (recvResult <= 0) {
printf("Socket receive()-error\n");
goto exit;
}
else
printf("Sock success\n");
printf("completed rx data\n");
//puts(udpBuf);
fprintf(udp, "%s", udpBuf);
//fwrite(udpBuf, sizeof(udpBuf), 1, udp);
}
inputData.noIteration--;
if (inputData.noIteration <= 0)*/
recvData-- ;
}
exit:
if(udp)
{
fclose(udp);
udp = 0;
}
//shutdown socket
closesocket(sockID);
fclose(udp);
return 0;
}
- output::::
UDP Packet Receiver
Enter Destination FEP IP Address : 192.168.13.25
Enter Destination port from which to receive data : 2013
Enter No.of iterations :
0
Socket Created
bind() is OK!
receiving data
Well, first off your bind call should use sizeof(fepAddr) (which I assume is struct sockaddr_in) instead of sizeof(struct sockaddr) to give it a chance of actually binding to the correct address.
Second, are you sure that someone is actually sending you data? otherwise recvfrom will block by default.

Resources