Running UDP client and server in different machines - c

I have a UDP client and a server running fine when run on the same computer. (Here for the client i have given 127.0.0.1 as the destination IP on the UDP client).
However when run on different machines, and replacing 127.0.0.1 with my the ip of the machine where server.c is present, the program doesnt work. The problem is i'm not getting any error message.
Below is the code for server and client. Please tell me any modifications to be performed to run the same over different machines(I'm using LINUX OS).
Note: My machines serverIP(machine where server.c is present): 10.60.5.945,
clientIP: 10.60.5.950
server.c:
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
int cont,create_socket,new_socket,addrlen,fd;
int bufsize = 1024;
int nameLen=0;
int client_address_size=0;
char *buffer = malloc(10);
char fname[256];
struct sockaddr_in address,client;
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
printf("The socket was created\n");
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(15000);
if (bind(create_socket,(struct sockaddr *)&address,sizeof(address))== 0)
printf("Binding Socket\n");
nameLen=sizeof(address);
if (getsockname(create_socket,(struct sockaddr *)&address,&nameLen)<0)
{
printf("\n\ngetsockname() error\n");
exit(3);
}
printf("Port assigned is %d\n", ntohs(address.sin_port));
client_address_size=sizeof(client);
if(recvfrom(create_socket,fname, 255,0,(struct sockaddr *) &client,&client_address_size)<0)
{
printf("\n\nrecvfrom() failed\n");
exit(4);
}
printf("A request for filename %s Received..\n", fname);
if ((fd=open(fname, O_RDONLY))<0)
{
perror("File Open Failed");
exit(0);
}
while((cont=read(fd, buffer, 10))>0)
{
sleep(1);
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size);
printf("\n\nPacket sent\n");
}
sendto(create_socket,"*",1,0,(struct sockaddr *) &client,client_address_size);
printf("Request Completed\n");
return close(create_socket);
}
client.c:
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
int create_socket,cont,res;
char *arg="127.0.0.1";
int bufsize = 1024;
int server_address_size=0;
char *buffer = malloc(10);
char fname[256];
struct sockaddr_in address;
int serv_addr_size = sizeof(address);
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
printf("The Socket was created\n");
address.sin_family = AF_INET;
address.sin_port = htons(15000);
address.sin_addr.s_addr=inet_addr(arg);
if (connect(create_socket,(struct sockaddr *) &address,sizeof(address)) == 0)
printf("The connection was accepted with the server %s...\n",arg);
printf("Enter The Filename to Request : ");
scanf("%s",fname);
res=sendto(create_socket, fname, sizeof(fname), 0,(struct sockaddr *) &address,sizeof(address));
if(res<0)
{
printf("\n\nSendto falied...\n");
exit(0);
}
printf("Request Accepted... Receiving File...\n\n");
server_address_size=sizeof(address);
printf("The contents of file are...\n\n");
while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,&serv_addr_size))>0)
{
if(buffer[cont-1]=='*')
break;
write(1, buffer, cont);
}
printf("\nEOF\n");
return close(create_socket);
}
Above is the code working fine when it is run on the same system. Please tell me the modifications to be made to run the above code on different machines. Thanks in advance.

Have you tried changing char *arg="127.0.0.1"; to the servers IP address? The IP address 10.60.5.945mentioned in your question, is not a valid IP.
Even better would be to take the IP (or even a hostname that you resolve) from argv[1].
ps. You can see the valid IPv4 addresses of your Linux box by typing: ip -4 a l scope global

Related

Regarding socket programming and how to modify the original server code so that it accepts any port number input?

Is there any way where I can modify the original server code so that it accepts any port number instead of the predefined one (i.e., port number 8989)? The Port number will be entered in the command line when testing the Server1.exe as follows: start server 8989
(also the main function parameters holds the port the command line arguments)
I tried doing it like as shown below, but when I went to my command prompt to run my server, it gave me:
Server1.c:7:23: fatal error: sys/socket.h:
No such file or directory
#include<sys/socket.h> as well as "compilation terminated"
#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<string.h>
#include<netdb.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
//#define MY_PORT 8989
#define MAXBUF 256
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET sockfd , clientfd;
struct sockaddr_in self;
char buffer[MAXBUF], buffer1[MAXBUF]; //modified
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
/*---create streaming socket---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
perror("Socket");
exit(errno);
}
printf("Socket created.\n");
/*---initialize address/port structure---*/
/* bzero(&self, sizeof(self));*/
self.sin_family = AF_INET;
self.sin_port = htons(12000); // Host to Network Short (16-bit)
self.sin_addr.s_addr = INADDR_ANY;
self.sin_addr.s_addr = inet_addr("172.20.10.2");
/*---assign a port number to the socket---*/
if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
{
perror("socket--bind");
exit(errno);
}
puts("Bind done");
/*---make it a "listening socket"---*/
if ( listen(sockfd, 20) != 0 )
{
perror("socket--listen");
exit(errno);
}
puts("Waiting for incoming connections...");
char *ip;
/*---forever... ---*/
while (1)
{
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
/*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);
printf("Connection Established\n");
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(client_addr.sin_addr), ip, INET_ADDSTRLEN);
// "ntohs(peer_addr.sin_port)" function is
// for finding port number of client
printf("connection established with IP : %s and PORT : %d\n", ip, ntohs(peer_addr.sin_port));
recv(clientfd, buffer1, 256, 0);
printf("Client : %s\n", buffer);
strcpy(buffer, "Hello");
send(clientfd, buffer, recv(clientfd, buffer, MAXBUF, 0), 0);
/*---close connection---*/
close(clientfd);
}
/*---clean up (should never get here!)---*/
close(sockfd);
WSACleanup();
return 0;
}

UDP socket binding windows 10 vs windows 7

I have been trying to bind a socket in windows 10 both in c (using cygwin) and python.
Both languages do not work, the c implementation returns: **"bind: Cannot assign requested address"**.
I'm not sure what the problem is since running the same code on windows 7 gives no problem.
Does anyone have any clue?
I include the c code:
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#include<unistd.h> //close
#include <sys/errno.h>
int main(int argc, char *argv[])
{
//initialize socket and structure
int socket_info;
struct sockaddr_in server;
//create socket
socket_info = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_info == -1) {
printf("Could not create socket.");
exit(0);
}
// zero out the structure
memset((char *) &server, 0, sizeof(server));
server.sin_family = AF_INET;
//Use this ip address
char pc_ip_addr[] = "192.168.100.47";
inet_pton(AF_INET, pc_ip_addr, &server.sin_addr.s_addr);
//Destination port
server.sin_port = htons( 12345 );
//Binding address to this server
if (bind(socket_info, (struct sockaddr *)&server, sizeof(server)) != 0) {
perror("Binding error");
exit(0);
}
puts("Server binding success.");
close(socket_info);
}

printing client ip when server is on same machine

I am writing a simple tcp echo client server code both my client and server code are running on the same machine i did bind two different addresses to client and server but client ip address is not getting printed when connected to server i changed addresses and still i was not able to print address i don't see any mistake in code.Is this my os issue or am i making some mistake.
my server code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define MAX_CLIENTS 10
#define MAX_DATA 1024
int main(int argc, char *argv[]){
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof(struct sockaddr_in);
int data_len;
char data[MAX_DATA+1];
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("server socket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
inet_aton(argv[2],&server.sin_addr.s_addr);
bzero(&server.sin_zero,0);
if(bind(sock, (struct sockaddr *)&server,sockaddr_len) == ERROR){
perror("bind");
exit(-1);
}
if(listen(sock, MAX_CLIENTS) == ERROR){
perror("listen");
exit(-1);
}
while(1){
if((new = accept(sock,(struct sockaddr *)&client,&sockaddr_len)) == ERROR){
perror("accept");
exit(-1);
}
//ip not getting printed
printf("New client connected from port no %d IP %s\n",ntohs(client.sin_port),inet_ntoa(client.sin_addr.s_addr));
data_len = 1;
while(data_len){
data_len = recv(new,data,MAX_DATA,0);
if(data_len){
send(new, data, data_len,0);
data[data_len] = '\0';
printf("Sent message: %s", data);
}
}
printf("Client disconnected\n");
close(new);
}
}
my client code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define BUFFER 1024
int main(int argc, char *argv[]){
struct sockaddr_in remote_server,client;
int sock,len;
char input[BUFFER];
char output[BUFFER+1];
client.sin_family = AF_INET;
client.sin_port = htons(3000);
inet_aton("127.0.2.8",&client.sin_addr.s_addr);
bzero(&client.sin_zero,0);
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("socket");
exit(-1);
}
int size = sizeof(struct sockaddr_in);
if(bind(sock, (struct sockaddr *)&client,size) == ERROR){
perror("bind");
exit(-1);
}
remote_server.sin_family = AF_INET;
remote_server.sin_port = htons(atoi(argv[2]));
remote_server.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&remote_server.sin_zero , 0);
if((connect(sock ,(struct sockaddr *)&remote_server , sizeof(struct sockaddr_in))) == ERROR){
perror("connect");
exit(-1);
}
while(1){
fgets(input, BUFFER, stdin);
send(sock, input, strlen(input) , 0);
len = recv(sock,output,BUFFER,0);
output[len] = '\0';
printf("%s\n",output);
}
close(sock);
}
This is the output:
New client connected from port no 3000 and IP
First of all you need two more includes in client as well as server
#include<arpa/inet.h> // for inet_aton(), inet_addr() and inet_ntoa()
#include<unistd.h> //for close()
Secondly,
The function declaration for inet_aton() and inet_ntoa() are respectively:
int inet_aton(const char *cp, struct in_addr *inp);
and
char *inet_ntoa(struct in_addr in);
So, You must pass the entire structure i.e xyzaddr.sin_addr instead of xyzaddr.sin_addr.s_addr(which is an int)
Hence make these changes as well:
In server:
inet_aton(argv[2],&server.sin_addr.s_addr); -> inet_aton(argv[2],&server.sin_addr);
inet_ntoa(client.sin_addr.s_addr) -> inet_ntoa(client.sin_addr)
In client:
inet_aton("127.0.2.8",&client.sin_addr.s_addr); -> inet_aton("127.0.2.8",&client.sin_addr);

How do i stop my tcp echo server to work the right way?

// A simple echo server
// ./server port_no
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<error.h>
#include<strings.h>
#include<unistd.h>
#include<arpa/inet.h>
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
main(int argc, char **argv)
{
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof(struct sockaddr_in);
int data_len;
char data[MAX_DATA];
if((sock = socket(AF_INET , SOCK_STREAM, 0)) == ERROR)
{
perror("server socket: ");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = INADDR_ANY;
bzero(&server.sin_zero,8);
if((bind(sock , (struct sockaddr *)&server, sockaddr_len)) == ERROR)
{
perror("bind : ");
exit(-1);
}
if((listen(sock, MAX_CLIENTS)) == ERROR)
{
perror("listen");
exit(-1);
}
while(1) //Better signal handling required
{
if((new == accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
{
perror("accept");
exit(-1);
}
printf("New Client connected from port no %d and IP %s\n",ntohs(client.sin_port),inet_ntoa(client.sin_addr));
data_len = 1;
while(data_len)
{
data_len = recv(new,data , MAX_DATA, 0);
if(data_len)
{
send(new, data, data_len, 0);
data[data_len] = '\0' ; // null the last byte to detect string
printf("Sent mesg: %s", data);
}
}
printf("Client disconnected\n");
close(new);
}
close(sock);
}
HI i have been learning socket programming in C . And recently i had written a code for tcp echo server. Server does shows connected when i use netstat command but as soon as i run the code using telnet it starts printing infinite messages instead of waiting for me to write a message in other terminal. Please help me figure out where i am i going wrong.
The reason for the infinite loop is the code
f((new == accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
It should instead be
f((new = accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
It's == vs =. With ==, the socket returned by accept() is never assigned to new, so calling recv() on it returns -1 (error in this case), and because the code doesn't check for the error, as pointed out Alan Au, the result is an infinite loop.
BTW, if you watch the compiler warnings or enable more warnings by using a switch, e.g. -Wall with gcc, you can usually get some good insight into possible issues with the code.

UDP client unable to receive data from the server

I have a UDP client and a UDP server. The flow of the program is: first the server is executed from the terminal, the terminal creates a socket and binds it and waits for a filename from the client. In another terminal the client is executed. Here also a socket is created, and a connection is established with the server. Then a filename is provided to the client. This filename is sent to the server using sendto() function. The server is able to receive filename from the client and the server is also sending the data in the file to the client. However the receiver on the other side keeps waiting for the data from the server.
The code for the UDP client and server is as shown below.
UDP Server:
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
int cont,create_socket,new_socket,addrlen,fd;
int bufsize = 1024;
int nameLen=0;
int client_address_size=0;
char *buffer = malloc(10);
char fname[256];
struct sockaddr_in address,client;
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
printf("The socket was created\n");
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(15000);
if (bind(create_socket,(struct sockaddr *)&address,sizeof(address))== 0)
printf("Binding Socket\n");
nameLen=sizeof(address);
if (getsockname(create_socket,(struct sockaddr *)&address,&nameLen)<0)
{
printf("\n\ngetsockname() error\n");
exit(3);
}
printf("Port assigned is %d\n", ntohs(address.sin_port));
client_address_size=sizeof(client);
if(recvfrom(create_socket,fname, 255,0,(struct sockaddr *) &client,&client_address_size)<0)
{
printf("\n\nrecvfrom() failed\n");
exit(4);
}
printf("A request for filename %s Received..\n", fname);
if ((fd=open(fname, O_RDONLY))<0)
{
perror("File Open Failed");
exit(0);
}
while((cont=read(fd, buffer, 10))>0)
{
//sleep(1);
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size);
printf("\n\nPacket sent\n");
}
printf("Request Completed\n");
return close(create_socket);
}
UDP Client:
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
int create_socket,cont;
char *arg="127.0.0.1";
int bufsize = 1024;
int server_address_size=0;
char *buffer = malloc(10);
char fname[256];
struct sockaddr_in address,server;
if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0)
printf("The Socket was created\n");
address.sin_family = AF_INET;
address.sin_port = htons(15000);
address.sin_addr.s_addr=inet_addr(arg);
if (connect(create_socket,(struct sockaddr *) &address,sizeof(address)) == 0)
printf("The connection was accepted with the server %s...\n",arg);
printf("Enter The Filename to Request : ");
scanf("%s",fname);
sendto(create_socket, fname, sizeof(fname), 0,(struct sockaddr *) &address,sizeof(address));
printf("Request Accepted... Receiving File...\n\n");
server_address_size=sizeof(server);
printf("The contents of file are...\n\n");
while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,sizeof(address)))>0)
{
write(1, buffer, cont);
}
printf("\nEOF\n");
return close(create_socket);
}
Where am i going wrong? Please provide a proper solution for the same.
Thanks in advance.
You are using the value-result arguments in recvfrom() wrong. A compiler should warn you about this very loudly. Recvfrom() will try to return a number to you in the 6th parameter, so you can not pass it a constant created with sizeof().
From the manpage:
The argument addrlen is a
value-result argument, which the caller should initialize before the call to the
size of the buffer associated with src_addr, and modified on return to indicate the
actual size of the source address.
I changed the recvfrom() loop like this and a file was successfully sent & received.
int serv_addr_size = sizeof(address);
while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,&serv_addr_size))>0)
{
write(1, buffer, cont);
}
Since you are calling connect() on the socket, you could also use recv(), like so:
recv(create_socket, buffer, 10, 0)
As some general advice, allways carefully check the return values from system and library calls (except maybe for printf()) and be prepared for all cases listed on the functions man-page under "return values".
EDIT The server side makes a similar error in the other direction. A parameter of sendto() that should just be the length of the passed struct, is passed as a pointer.
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size);
Should be
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size);
Just let me to write a valid example. I've tried to rewrite your own code, but I prefer to show you a nice example. Just a few minutes...
---EDIT---
Ok, here I am. Forgive me for the time I spent, but I preferred to read carefully the code.
Here your two files:
Server implementation
Client implementation
Really hope I helped you.

Resources