printing client ip when server is on same machine - c

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);

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);
}

Send a UDP message from Server to Client

I am experimenting with sending a message from a server to a client using UDP sockets... however, my client is not receiving any messages. Any feedback would be greatly appreciated!
EDIT: maybe I should clarify that the message seems to be sending successfully, however when I run the client it gets stuck on waiting for data... any pointers as to why this is happening would be appreciated!
UDP SERVER
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "127.0.0.1"
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
void die(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen = sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
//create a UDP socket
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
//bind socket to port
if( bind(s , (struct sockaddr*)&si_other, sizeof(si_other) ) == -1)
{
die("bind");
}
else
{
printf ("Success!\n");
}
while(1)
{
printf("Enter message : ");
gets(message);
//send the message
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1)
{
die("sendto()");
}
else
{
printf ("Success!\n");
}
}
close(s);
return 0;
}
UDP CLIENT
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to send data
void die(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, slen=sizeof(si_other), recv_len;
char buf[BUFLEN];
char message[BUFLEN];
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
while(1)
{
printf("Waiting for data...");
fflush(stdout);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)
{
die("recvfrom()");
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n" , buf);
}
close(s);
return 0;
}
Call bind() from the client and not the server
you need to bind your client, not your server.

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.

Running UDP client and server in different machines

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

Resources