Socket error 10054 when receiving buffer data - winsock2.h library - c

I'm new to websocket programming. I have a client and a server running separately, both compiled from C on Windows 7. The server is running fine, with binding, connection and messaging being made successfully. However, what intrigues me is that it doesn't show up in netstat command listening on the determined port (9002). When the client is initialized, it gets the error 10054, which is "Connection reset by peer". I have already enabled both applications on the Window's firewall, restarted the machine but I haven't been able to figure out what is happening.
Client side code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define PORT 9002
int main(int argc, char *argv[])
{
WSADATA wsa;
printf("\nInitializing Winsock... ");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
printf("Initialized.\n");
SOCKET network_socket; // create a socket
// network_socket = socket(domain, type, protocol)
network_socket = socket(AF_INET, SOCK_STREAM, 0);
// domain: AF_INET (IPv4 protocol) / AF_INET6 (Ipv6 protocol)
// type: SOCK_STREAM (TCP protocol) / SOCK_DGRAM (UDP protocol)
// protocol: Internet Protocol (IP) - 0
if (network_socket == INVALID_SOCKET) {
printf("Socket creation error: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
// specify an address for the socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET; // specifies protocol IPv4
server_address.sin_port = htons(PORT); // specifies port
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
if (inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr) <= 0 ) {
printf("Invalid address / Address not supported: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
// connection
int connection_status = connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address));
// check for error in the connection
if (connection_status < 0) {
printf("Connection error: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
// Receive data from the server
char buffer[256]; // server response
if ((recv(network_socket, buffer, sizeof(buffer), 0)) == SOCKET_ERROR) {
printf("Receive error: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
// print the server's response
printf("The server sent the data: %s\n", buffer);
// close the socket
closesocket(network_socket);
WSACleanup();
return 0;
}
Server side code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define PORT 9002
int main(int argc, char *argv[])
{
WSADATA wsa;
printf("\nInitializing Winsock... ");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
puts("Initialized!");
// create the server socket
SOCKET server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == INVALID_SOCKET) {
printf("Could not create socket: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
// bind the socket to our specified IP and port
if ((bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address))) == SOCKET_ERROR) {
printf("Binding failed: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
puts("Binding done!");
// listen for connections
listen(server_socket, 5);
// accept the connection
puts("Waiting for incoming connections...");
SOCKET client_socket;
if (client_socket = accept(server_socket, NULL, NULL) == INVALID_SOCKET) {
printf("Error accepting connections: %d\n", WSAGetLastError());
WSACleanup();
return EXIT_FAILURE;
}
puts("Connection accepted!");
// send the message
char *server_message = "You have reached the server!";
send(client_socket, server_message, sizeof(server_message), 0);
puts("Message sent!");
// close the socket
closesocket(server_socket);
WSACleanup();
return 0;
}
Client side program outputs the following:
Initializing Winsock... Initialized.
Receive error: 10054
Server side program outputs the following:
Initializing Winsock... Initialized!
Binding done!
Waiting for incoming connections...
Connection accepted!
Message sent!
Please, any hints and ideas will be greatly appreciated. Thanks.

Related

socket binding failed (address already in use, even with SO_REUSEADDR)

I am working in a simple socket project. I would like to know:
why error messages appear before telnet localhost 5678?
why SO_REUSEADDR (between socket() and bind()) don't work, and what else I should try?
Code Output Message:
bind error
Error opening file: Address already in use
telnet localhost 5678
[+]Server Socket is created.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define BUFSIZE 1024 // Buffer Size
#define PORT 5678
int main() {
printf("telnet localhost 5678\n");
int rfd; // socket descriptor
int clientfd; // client descriptor
struct sockaddr_in client; // Client Socket address
socklen_t client_len; // Length of Client Data
char input[BUFSIZE]; // Client Data -> Server
int bytes_read; // Client Bytes
// 1. socket() = create a socket, SOCK_STREAM = TCP
rfd = socket(AF_INET, SOCK_STREAM, 0);
if (rfd < 0) {
fprintf(stderr, "socket error\n");
exit(-1);
}
printf("[+]Server Socket is created.\n");
// optional
int enable = 1;
if (setsockopt(rfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
fprintf(stderr, "setsockopt(SO_REUSEADDR) failed");
//Initialize the server address by the port and IP
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET; // Internet address family: v4 address
server.sin_addr.s_addr = INADDR_ANY; // Server IP address
server.sin_port = htons(PORT); // Server port
// 2. bind() = bind the socket to an address
int brt = bind(rfd, (struct sockaddr *) &server, sizeof(server));
if (brt < 0) {
int errnum;
errnum = errno;
fprintf(stderr, "bind error\n");
fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
exit(-1);
}
printf("[+]Bind to port %d\n", PORT);
// 3. listen() = listen for connections
int lrt = listen(rfd, 50);
if (lrt < 0) {
printf("listen error\n");
exit(-1);
}
if (lrt == 0) {
printf("[+]Listening....\n");
}
// non-stop loop
while (1) {
// 4. accept() = accept a new connection on socket from client
clientfd = accept(rfd, (struct sockaddr *) &client, &client_len);
if (clientfd < 0) {
fprintf(stderr, "accept failed with error %d\n");
exit(-1);
}
printf("Client connected\n");
...
close(clientfd);
printf("Client disconnected\n");
}
close(rfd);
}
I'm assuming that you are using Linux. If you want to rebind to an address, you should use SO_REUSEPORT not SO_REUSEADDR. Name is really misleading. But make sure that you know how it works and whether you really want to use it or not.
You can check difference here: How do SO_REUSEADDR and SO_REUSEPORT differ?

Connect Keeps Failing With Error 10049 in C

I'm new to socket programming and this is my first server-client program. The program was working perfectly fine at first, but when I copied my code from Server.c and Client.c to a new project in Visual Studio, my client is now refusing to connect and throws the error 10049. I can still connect to my server if I use telnet from command prompt.
I am surprised as to why my client would stop working when I copy the code to another empty project, nothing else has changed.
I have tried changing IP addresses, port numbers and port forwarding using my public address to no avail. I have confirmed my computer's IP using ipconfig and it is correctly inputted in my code, as well as the port number. The program compiles fine with no errors whatsoever.
Server.c
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <WS2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
void start_server(const char* ip_address, int port_number);
int server_sock, client_sock;
void main(int argc, char* argv[])
{
start_server("192.168.0.24", 100);
system("pause");
}
void start_server(const char* ip_address, int port_number)
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup() failed with error: %d\n", iResult);
return 1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port_number);
InetPton(AF_INET, "", &server_addr.sin_addr.s_addr);
server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_sock == INVALID_SOCKET)
{
printf(L"Socket creation failed with error: %ld\n", WSAGetLastError());
}
else
{
printf("Socket created!\n");
}
int bind_status = bind(server_sock, (struct sockaddr*) & server_addr, sizeof(server_addr));
if (bind_status == SOCKET_ERROR) {
wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
}
else
{
printf("Bind was successful!\n");
}
int listen_status = listen(server_sock, 3);
if (listen_status == -1)
{
wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
}
else
{
printf("Listening...\n");
}
client_sock = accept(server_sock, NULL, NULL);
if (client_sock == -1)
{
wprintf(L"client socket failed with error: %ld\n", WSAGetLastError());
}
else
{
printf("Accepted new client!\n");
}
}
Client.c
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <WS2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
void connect_server(const char* ip_address, int port_number);
int sock;
void main()
{
connect_server("192.168.0.24", 100);
send(sock, "test", 5, 0);
system("pause");
}
void connect_server(const char* ip_address, int port_number)
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf("WSAStartup() failed with error: %d\n", iResult);
exit(1);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port_number);
InetPton(AF_INET, ip_address, &server_addr.sin_addr.s_addr);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Socket creation failed with error: %d\n", WSAGetLastError());
}
else
{
printf("Socket created!\n");
}
int connection_status = connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
if (connection_status == SOCKET_ERROR)
{
printf("Connection failed with error: %d\n", WSAGetLastError());
}
else
{
printf("Connected.\n");
}
}
A very fast/simple search for WSA error 10049 results in:
Winsock error 10049 typically occurs when you attempt to create a socket with an address not on this machine. For example if you have MDaemon running on a machine with an IP address of 192.168.0.1 and you attempt to bind MDaemon to 192.168.0.100 you will receive this error message.
So, you need to correct the IP address for the new computer.
Try using your code with loopback address 127.0.0.1. If it works then definitely problem is with the combination of IP and Port number. Maybe use ipconfig /reset to reset your ip address.

Server Client application in c using TCP/IP protocol

Hi, I am developing Server client between two different operating
systems. I am executing server on Ubuntu 14.04 & Client on Windows.
/* Simple Server code on TCP/IP protocol */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define length 512
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno; //Declare variable for Socket and port
socklen_t clilen; //Client address and port no
char buffer[length]; //Buffer for message
struct sockaddr_in serv_addr, cli_addr; //Srtructure for server and Client address
int n; //Check whether listen,accept,read,write process done
FILE *fileptr; //File pointer
int datasize;
/* Check Portno. provided or not */
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
/*Create socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr)); //Clear memory for Server address
portno = atoi(argv[1]); //Convert portno in to Integer from ASCII
/*Server address and all other details */
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/*Bind socket*/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
/*Listening to socket and waiting for users(max.5) */
listen(sockfd,5);
clilen = sizeof(cli_addr); //Size of Client address
/*Accept users*/
newsockfd= accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
if (newsockfd< 0)
error("ERROR on accept");
/*File operations */
char* fs_name = "/home/ankur/Desktop/RTSIM_Dump.csv";
fileptr=fopen(fs_name,"r"); //Open file
/*Write and Read operation to socket*/
bzero(buffer,length);
while((datasize = fread(buffer,sizeof(char),length,fileptr))>0)
{
if(send(newsockfd,buffer,datasize,0)<0)
{
fprintf(stderr, "ERROR: Failed to send file :%s (errno = %d)\n",fs_name,errno);
break;
}
bzero(buffer,length);
}
fclose(fileptr); //Close file
close(newsockfd); //Close to accept client
close(sockfd); //close socket
return 0;
}
//Client code:
------------------------------------------------------------------------------#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "2222"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char sendbuf[DEFAULT_BUFLEN];
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen;
FILE *fileptr;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// 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_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
//Receive file from Server and save it.
fileptr = fopen("/Desktop/RTSIM_Dump.csv","w");
if (fileptr == NULL)
{
printf("ERROR:Create/Open file");
exit(1);
}
int write_sz;
memset(recvbuf,0,DEFAULT_BUFLEN);
while((recvbuflen = recv(ConnectSocket,recvbuf,DEFAULT_BUFLEN,0))>0)
{
write_sz = fwrite(recvbuf,sizeof(char),recvbuflen,fileptr);
if(write_sz < recvbuflen)
{
printf("File write failed.\n");
}
memset(recvbuf,0,DEFAULT_BUFLEN);
if(recvbuflen == 0 || recvbuflen != 512)
{
break;
}
}
if(recvbuflen < 0)
{
printf("recv() timed out.\n");
}
// cleanup
fclose(fileptr);
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
------------------------------------------------------------------------------ I am getting errno 104 on server (Ubuntu) & create/open file error on
Windows.
Thanks in advance!!!
I checked server client on Ubuntu , it works perfectly but when i
tried it with Windows client. It gives me error during execution.
fileptr = fopen("/Desktop/RTSIM_Dump.csv","w");
That is incorrect path for windows. More proper would be "\Desktop\RTSIM_Dump.csv". Note that the directories in the path must exist and have appropriate permissions.
Where do you get error 104 in server?

UDP client not receiving UDP server message

Hai friends I am a newbie learning winsock2. the following is my udp server and client programs.
I this program the client does not know the ip address of the server but knows only the port. But the server broadcasts a message all over the network.
when the client gets the message it traces back the ip of the server and connects to it.
Both my server and client show no error while compiling.
But while Executing the client's recvfrom() statement shows error
the following are the part of my code.
SERVER CODE:
#include "stdafx.h"
#include<stdio.h>
#include<WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s=(SOCKET)x;
char bro[200]="I am SERVER";
struct sockaddr_in hum;
hum.sin_family=AF_INET;
hum.sin_addr.s_addr=INADDR_BROADCAST;
hum.sin_port=htons(8888);
while (1)
{
if(sendto(s,bro,sizeof(bro),0,(struct sockaddr *)&hum,sizeof(hum))==SOCKET_ERROR)
{
printf("\nBroadcast failed ERROR CODE : %d\n",WSAGetLastError());
exit(1);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
struct sockaddr_in hum;
int opt=1;
//Initializing winsock2
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket Creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
{
printf("\nUDP Socket not created ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//socket defenition
hum.sin_family=AF_INET;
hum.sin_addr.s_addr=INADDR_ANY;
hum.sin_port=htons(8888);
//Broadcast permission
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nBroadcast permissions failed ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP SOCKET Binding
if((bind(s,(sockaddr *)&hum,sizeof(hum)))==SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP connection thread
DWORD th;
CreateThread(NULL,0,UDPCONN,(LPVOID)s,0,&th);
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int slen;
char message[300];
int opt=1;
SOCKET s;
struct sockaddr_in sent;
//Initializing winsock
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))== SOCKET_ERROR)
{
printf("\nUDP socket creation failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP socket definition
sent.sin_family=AF_INET;
sent.sin_addr.s_addr=INADDR_ANY;
sent.sin_port=htons(8888);
//UDP Receiving broadcasted data
slen=sizeof(sent);
//fflush(stdout);
memset(message,'\0',300);
if((recvfrom(s,message,sizeof(message),0,(struct sockaddr *)&sent,&slen))<0)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
puts("\nGot server broadcast\n");
puts("\nTracing server ip\n");
getpeername(s,(sockaddr *)&sent,&slen);
...
}
Here my client throw an error
UDP Broadcast not received ERROR CODE : 10022
Description of the error code 10022 : Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.
According to the error description one of the arguments in the recvfrom() function is invalid. But i could not find out the invalid argument .
Please help me clear the error.
If you read the recvfrom() documentation, it tells you exactly why you are getting the error in your client code:
Parameters
s [in]
A descriptor identifying a bound socket.
...
WSAEINVAL
The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.
You are not calling bind() on the socket before calling recvfrom(). More importantly, you cannot bind() the client and server to the same IP/port when they are running on the same machine. Change the port that you broadcast to, and then have the client bind to that port.
Also, the last two parameters of recvfrom() provide you with the IP/Port of the datagram sender. They are not for specifying the network adapter to read datagrams on. You do not need to use getpeername() in this situation.
There are some other issues with your code:
On the client side, socket() returns INVALID_SOCKET on failure, not SOCKET_ERROR.
On the server side, you really should not be using INADDR_BROADCAST. You should bind() the server socket to a specific network adapter and then sendto() its particular subnet broadcast IP, which you can calculate using GetAdaptersInfo() or GetAdaptersAddresses().
And on both sides, you cannot use WSAGetLastError() if WSAStartup() fails, that is why WSAStartup() returns the error code directly. And you are not closing the sockets before calling WSACleanup();
Try this:
SERVER CODE:
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s = (SOCKET)x;
char bro[200] = "I am SERVER";
struct sockaddr_in hum;
memset(&hum, 0, sizeof(addr));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_BROADCAST; // TODO: replace with subnet broadcast IP
hum.sin_port = htons(8887);
while (1)
{
if (sendto(s, bro, sizeof(bro), 0, (struct sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nBroadcast failed ERROR CODE : %d\n", WSAGetLastError());
return 1;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
struct sockaddr_in hum;
int err, opt=1;
//Initializing winsock2
WSADATA wsa;
err = WSAStartup(MAKEWORD(2,2), &wsa);
if (err != 0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n", err);
return 1;
}
//UDP Socket Creation
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == INVALID_SOCKET)
{
printf("\nUDP Socket not created ERROR CODE : %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//socket defenition
memset(&hum, 0, sizeof(hum));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_ANY; // TODO: replace with a specific NIC IP
hum.sin_port = htons(8888);
//Broadcast permission
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
printf("\nBroadcast permissions failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP SOCKET Binding
if (bind(s, (sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP connection thread
DWORD th;
HANDLE hThread = CreateThread(NULL,0, UDPCONN, s, 0, &th);
if (!hThread)
{
printf("\nUDP thread failed ERROR CODE : %u\n", GetLastError());
closesocket(s);
WSACleanup();
return 1;
}
// do other things, wait for thread to terminate ...
DWORD exitCode = 0;
GetExitCodeThread(hThread, &exitCode);
CloseHandle(hThread);
closesocket(s);
WSACleanup();
return exitCode;
}
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int addrlen, msglen;
char message[300];
int err, opt=1;
SOCKET s;
struct sockaddr_in hum, addr;
//Initializing winsock
WSADATA wsa;
err = WSAStartup(MAKEWORD(2,2), &wsa);
if (err != 0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n", err);
return 1;
}
//UDP Socket creation
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == INVALID_SOCKET)
{
printf("\nUDP socket creation failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP socket definition
memset(&hum, 0, sizeof(addr));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_ANY;
hum.sin_port = htons(8887);
//UDP SOCKET Binding
if (bind(s, (sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP Receiving broadcasted data
addrlen = sizeof(addr);
msglen = recvfrom(s, message, sizeof(message), 0, (struct sockaddr *)&addr, &addrlen);
if (msglen == SOCKET_ERROR)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
printf("\nGot server broadcast\n");
printf("\nServer ip: %s, port: %hu\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
printf("\nMessage: %.*s\n", msglen, message);
...
}
Whatever method i tried sending a broadcast from server and receiving the broadcast from client is not working efficiently.
Instead i done the reverse i.e send a broadcast from client to search for the server is working perfectly.
Here is my modified code.
SERVER CODE:
#include "stdafx.h"
#include<stdio.h>
#include<WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s=(SOCKET)x;
struct sockaddr_in server;
int len;
char buf[500]=("I am server");
char message[500];
len=sizeof(server);
int opt=1;
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
{
printf("\nSocket creation failed. ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(8888);
if(setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt))<0)
{
printf("\nSetting broadcast failed : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
if((bind(s,(sockaddr *)&server,sizeof(server)))==SOCKET_ERROR)
{
printf("\nBind failed. ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
while(1)
{
fflush(stdout);
memset(message,'\0', 500);
//try to receive some data, this is a blocking call
if (recvfrom(s, message, 500, 0, (struct sockaddr *) &server,&len) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
ExitThread(NULL);
}
if(sendto(s,buf,sizeof(buf),0,(struct sockaddr *)&server,sizeof(server))==SOCKET_ERROR)
{
printf("\nIP Broadcast failed ERROR code : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
//struct sockaddr_in hum;
int opt=1;
//Initializing winsock2
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n",WSAGetLastError());
return 1;
}
s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
//UDP connection thread
DWORD th;
CreateThread(NULL,0,UDPCONN,(LPVOID)s,0,&th);
closesocket(s);
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int slen;
char message[600];
char buf[300]=("Hai server");
int opt=1;
SOCKET s;
struct sockaddr_in sent;
//TCP Connection data
SOCKET t;
struct sockaddr_in server;
char messag[300],server_reply[300];
int recv_size;
//Initializing winsock
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))== INVALID_SOCKET)
{
printf("\nUDP socket creation failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP socket definition
sent.sin_family=AF_INET;
sent.sin_addr.s_addr=INADDR_BROADCAST;
sent.sin_port=htons(8888);
if (sendto(s, buf, sizeof(buf) , 0 , (struct sockaddr *) &sent,sizeof(sent)) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//UDP Receiving broadcasted data
slen=sizeof(sent);
fflush(stdout);
memset(message,'\0',300);
if((recvfrom(s,message,sizeof(message),0,(struct sockaddr *)&sent,&slen))<0)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
puts("\nGot server broadcast\n");
puts("\nTracing server ip\n");
getpeername(s,(sockaddr *)&sent,&slen);
closesocket(s);
Both the codes here works perfectly fine in visual studios 2012.
Also this is just one part of my whole big program. But still this part works perfectly fine independently.
So please make sure you compiled and run the program before posting negative comments.

server recieving some junk value from the client?

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <winsock.h>
#pragma once
#pragma comment (lib, "ws2_32.lib")
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <winsock.h>
#include <io.h>
SOCKET sock;
SOCKET fd;
char recv_data[10];
int port = 18001;
void CreateSocket()
{
struct sockaddr_in server, client; // creating a socket address structure: structure contains ip address and port number
printf("Initializing Winsock\n");
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup (wVersionRequested, &wsaData) != 0){
printf("Winsock initialised failed \n");
} else {
printf("Initialised\n");
}
// create socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
// create socket address of the server
memset( &server, 0, sizeof(server));
// IPv4 - connection
server.sin_family = AF_INET;
// accept connections from any ip adress
server.sin_addr.s_addr = htonl(INADDR_ANY);
// set port
server.sin_port = htons(port);
//Binding between the socket and ip address
if(bind (sock, (struct sockaddr *) &server, sizeof(server)) < 0)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
//Listen to incoming connections
if(listen(sock,3) == -1){
printf("Listen failed with error code: %d", WSAGetLastError());
}
printf("Server has been successfully set up - Waiting for incoming connections");
int len;
len = sizeof(client);
fd = accept(sock, (struct sockaddr*) &client, &len);
if (fd < 0){
printf("Accept failed");
}
//echo(fd);
printf("\n Process incoming connection from (%s , %d)", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
//closesocket(fd);
}
int main()
{
CreateSocket();
while(1)
{
if(fd == -1)
{
printf("socket error\n");
}
else
{
recv(fd, recv_data, 9, 0);
printf("value is %s", recv_data);
}
}
return 0;
}
The above is a server code : I am creating a socket and accepting the data from the client. The client is sending a data and the server is accepting it.
If the client sends a to the server then the server will add some junk characters to it. If the client sends 4 characters then it will receive all the four characters. if the client sends one or two characters :Why the server is receiving some junk value ??
This is because, recv does not append NULL character at the end of the string. You have to explicitly add the NULL character. So, use return value of recv call and use it to append the NULL character.
int retval;
retval = recv(fd, recv_data, 9, 0);
if(retval != SOCKET_ERROR) {
recv_data[retval] = '\0';
printf("value is %s", recv_data);
}
'\0' is the only character which will differ you from char array and string.
Since you are using %s to print the string it is necessary to add the '\0' character at the end.

Resources