i've done a simple client/server program where the server wait for an external connection and return the connection-socket if the port number of the client is in the range of [1025-2048] otherwise return -1. The problem is that when i get the port number by the client adress (which should be stored in the sockaddr structure) it says me that the client port number is zero, but in the client program i've set the client portnumber to 1999.
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int function(int fd_socket) {
int fd_socket_acc;
int len;
int port;
struct sockaddr_in client_addr;
puts("WAITING FOR CLIENT...");
fd_socket_acc = accept(fd_socket, (struct sockaddr*)&client_addr, &len);
puts("CONNECTION DONE.");
port = ntohs (client_addr.sin_port);
printf("client port number: %d \n", port);
if (port >= 1024 && port <= 2048) {
close (fd_socket_acc);
return fd_socket_acc;
}
else {
close(fd_socket_acc);
return -1;
}
}
int main(int argc, char *argv[]) {
int fd_socket;
struct sockaddr_in local_addr;
fd_socket = socket(AF_INET, SOCK_STREAM, 0);
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(1887);
local_addr.sin_addr.s_addr = INADDR_ANY;
bind(fd_socket, (struct sockaddr*)&local_addr, sizeof(local_addr));
listen(fd_socket, 3);
function(fd_socket);
//close(fd_socket);
}
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
int main(int argc, char *argv[]) {
int fd_socket;
struct sockaddr_in local_addr;
struct sockaddr_in server_addr;
struct hostent *hp;
fd_socket = socket(AF_INET, SOCK_STREAM, 0);
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(1999);
local_addr.sin_addr.s_addr = INADDR_ANY;
bind(fd_socket, (struct sockaddr*)&local_addr, sizeof(local_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(1887);
//hostname is "ubuntu"
hp = gethostbyname("ubuntu");
bcopy(hp->h_addr, &server_addr.sin_addr, 4);
printf("%d \n", ntohs(local_addr.sin_port));
connect(fd_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
wait(2);
close(fd_socket);
}
If i get the port number in client with a printf("%d", ntohs(local_addr.sin_port)) it stamps correctly 1999, but if i get the port number of client in server with printf("%d", ntohs(client_addr.sin_port)) it stamps 0. Why?
thanks in advance!
In order to obtain the client port number in client_addr through accept you have to tell accept how big that buffer is by setting
socklen_t len = sizeof(client_addr);
You can alternatively retrieve it by calling afterwards
len = sizeof(client_addr);
getpeername(fd_socket_acc, (struct sockaddr*)&client_addr, &len);
Maybe because you do not set the variable len to anything, and I suspect that your compiler sets it to 0.
What happens is that you try to accept with an undefined len size.
Adding len=sizeof( struct sockaddr_in ); before making a call to accept would help to fill the passed client_addr correctly.
Related
Here is the code TCP/IP client – server. The program works like this, first is the client which connect with server and printf hello. The server on the another side if the connection has successfully done printf a msg for connection with the port. So my question is how to use fork() function on server to create a multi clients system with one server.
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SIZE 1024
int main(int argc, char *argv [])
{
int sock, i=1 ;
char msg[SIZE],reply[SIZE];
struct sockaddr_in addr; // Internet socket
addr.sin_family = AF_INET; // Internet socket opou exei thn oikogeneia address IP kai provides the communication of server-client
inet_aton(argv [1], &addr.sin_addr);
addr.sin_port = htons(atoi(argv[2]) ) ; // metatroph byte pc se byte IP
sock = socket(AF_INET, SOCK_STREAM, 0); // Stream socket kanei to connection creat one " file descriptor " ppou omos den einai akoma etoimos gia thn epikinonia
connect(sock, ( struct sockaddr *)&addr, sizeof(addr)); // the last step and the finally connection from one socket to another client-server
prontf("hello");
strcpy(msg,"") ;
strcpy(reply,"");
close(sock);
return 0;
}
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SIZE 1024
#define STR_SIZE 100 //STR_SIZE doesn't have to be a constant
int main(int argc, char *argv [])
{
int psock, sock,cli_addr_len,i,j,res1;
char msg[SIZE];
struct sockaddr_in addr,cli_addr; // Internet socket
char reply[SIZE];
memset(&cli_addr, 0, sizeof(cli_addr));
cli_addr_len = sizeof(cli_addr);
addr.sin_family = AF_INET; // Internet socket
addr.sin_addr.s_addr = htonl(INADDR_ANY); // All interfaces
addr.sin_port = htons(atoi(argv [1]) ) ;
psock = socket(AF_INET, SOCK_STREAM, 0); // Stream socket
bind(psock, ( struct sockaddr *)&addr, sizeof(addr)); // assigning a name to a sock
listen (psock, 1) ;
strcpy(msg,"") ;
printf("\n waiting for new connection (port : %s) ... \n", argv [1]);
sock = accept(psock, (struct sockaddr *)&cli_addr, &cli_addr_len); // accept and take request - sock from the queue to connection
printf("connection established...\n");
close(sock);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[]){
// established the socket
char inputBuffer[256] = {};
char message[] = {"Hi this is the server.\n"};
int sockfd = 0;
int forClientSocketfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1) printf("Fail to create the socket.");
// socket connection
struct sockaddr_in serverInfo, clientInfo;
int addrlen = sizeof(clientInfo);
bzero(&serverInfo, sizeof(serverInfo));
serverInfo.sin_family = PF_INET;
serverInfo.sin_addr.s_addr = INADDR_ANY;
serverInfo.sin_port = htron(10024);
bind(sockfd, (struct sockaddr *) &serverInfo, sizeof(serverInfo));
listen(sockfd, 5);
while(1){
forClientSocketfd = accept(sockfd, (struct sockaddr*) &clientInfo, &addrlen);
send(forClientSocketfd, message, sizeof(message), 0);
recv(forClientSocketfd, inputBuffer, sizeof(inputBuffer), 0);
printf("Received from client: %s\n", inputBuffer);
}
return 0;
}
This is the code for socket programming that I seen through from the net. when I compiled it, it throw the error message as below. Having no idea what's going on, even though searching through the internet. p.s. Client operate as normal.
enter image description here
you have a typo on line number 24 it should be htons and not htron
htons()
The htons function takes a 16-bit number in host byte order and returns a 16-bit number in network byte order used in TCP/IP networks(the AF_INET or AF_INET6 address family). The htons function can be used to convert an IP port number in host byte order to the IP port number in network byte order
also add the stdio header file to your code to remove the other warnings
heres the final corrected code with no warnings or errors.
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
// established the socket
char inputBuffer[256] = {};
char message[] = {"Hi this is the server.\n"};
int sockfd = 0;
int forClientSocketfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
printf("Fail to create the socket.");
// socket connection
struct sockaddr_in serverInfo, clientInfo;
int addrlen = sizeof(clientInfo);
bzero(&serverInfo, sizeof(serverInfo));
serverInfo.sin_family = PF_INET;
serverInfo.sin_addr.s_addr = INADDR_ANY;
serverInfo.sin_port = htons(10024);
bind(sockfd, (struct sockaddr *)&serverInfo, sizeof(serverInfo));
listen(sockfd, 5);
while (1)
{
forClientSocketfd = accept(sockfd, (struct sockaddr *)&clientInfo, &addrlen);
send(forClientSocketfd, message, sizeof(message), 0);
recv(forClientSocketfd, inputBuffer, sizeof(inputBuffer), 0);
printf("Received from client: %s\n", inputBuffer);
}
return 0;
}
I have the following code for client and server
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int socket_fd;
struct sockaddr_in dest;
struct hostent *hostptr;
struct { char head; u_long body; char tail; } msgbuf;
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
bzero((char *) &dest, sizeof(dest)); /* They say you must do this */
hostptr = gethostbyname(argv[1]);
dest.sin_family = (short) AF_INET;
bcopy(hostptr->h_addr, (char *)&dest.sin_addr,hostptr->h_length);
dest.sin_port = htons((u_short)0x3333);
msgbuf.head = '<';
msgbuf.body = htonl(getpid()); /* IMPORTANT! */
msgbuf.tail = '>';
sendto(socket_fd,&msgbuf,sizeof(msgbuf),0,(struct sockaddr *)&dest,
sizeof(dest));
return 0;
}
server:
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int socket_fd, cc, fsize;
struct sockaddr_in s_in, from;
struct { char head; u_long body; char tail;} msg;
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
bzero((char *) &s_in, sizeof(s_in)); /* They say you must do this */
s_in.sin_family = (short)AF_INET;
s_in.sin_addr.s_addr = htonl(INADDR_ANY); /* WILDCARD */
s_in.sin_port = htons((u_short)0x3333);
printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in));
for(;;) {
fsize = sizeof(from);
cc = recvfrom(socket_fd,&msg,sizeof(msg),0,(struct sockaddr *)&from,&fsize);
//printsin( &from, "recv_udp: ", "Packet from:");
printf("Got data ::%c%ld%c\n",msg.head,(long) ntohl(msg.body),msg.tail);
fflush(stdout);
}
return 0;
}
I'm looking for a way to change this code so that:
1.The client will send my name to the server and then will receive the server response.
2.On the server side, the server will receive the client name (instead of the current msg structure) and will send back its name.
I'm assuming I should just put my name in the msgbuf.body like this
msgbuf.head = '<';
msgbuf.body = 'liana';
msgbuf.tail = '>';
and delete the
msgbuf.body = htonl(getpid()); line.
or maybe make a new string for my name like this string name="liana";
and put it in the msgbuf.body like this msgbuf.body=name;(???)
is this the right deriction?
for reciving the response of the server I assume it is the same way as it was done for the server
should I add to client something like this?
int socket_fd, cc, fsize; // the socket that we receive to
struct sockaddr_in s_in, from; // decleration of the server and sending
(to the server) struct
fflush(stdout);//to ensure that whatever you just wrote to a file/the console is indeed written out on disk/the console.
bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in));// conecting
between
the socket and all the details we entered
for(;;) {//infinite loop
fsize = sizeof(from);//set the size of the socket we resive to
cc = recvfrom(socket_fd,&msg,sizeof(msg),0,(struct sockaddr
*)&from,&fsize);//recive massage using UDP protocol
printf("Got data ::%c%ld%c\n",msg.head,(long) ntohl(msg.body),msg.tail);
//print the whole massage
fflush(stdout);//to ensure that whatever you just wrote to a file/the
console is indeed written out on disk/the console.
}
and just leave it like this without changing anything?
**how can I make the server receive the my name (instead of the current msg
structure)and send it back?
should I send it back using the
sendto(socket_fd,&msgbuf,sizeof(msgbuf),0,(struct sockaddr *)&dest,
sizeof(dest));
line?
**if I cant use the structure anymore how should i change this line?****
any help whould be appreciated,I'm kind of new to C and never worked with the client/server model
Problem:
I need some help with an error in my code. The chat client works when I only have one client running but if i use more clients. Only the last client messages will show up on my server. my client.c seems to work since it is sending but for some reason recv() is not getting the previous client send().
How code works:
I set up my server and spawn a new thread whenever a new client connects. the thread will handle the messages i get form the client and print it on the server screen.
Code:
CLIENT.C
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(int argc, char ** argv){
//get port
//int port = atoi(argv[1]);
int server_port = atoi(argv[1]);
char * name =argv[2];
int namelength = strlen(name);
//set up server adress and socket
int sock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(server_port);
//connect
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("connect failed");
exit(1);
}
//set up client name
char * buff = malloc(5000*sizeof(char));
//get the chatting
//char * other_message = malloc(5000*sizeof(char));
while(1){
printf("ENTER MESSAGE:\n");
char message[5000];
strcpy(message, name);
strcat(message,": ");
printf("%s", message);
scanf("%[^\n]",buff);
getchar();
strcat(message,buff);
int sent = send(sock , message , strlen(message) , MSG_DONTWAIT );
if (sent == -1)
perror("Send error: ");
else
printf("Sent bytes: %d\n", sent);
}
return 0;
}
SERVER.C
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
pthread_t * threads = NULL;
int * client_fd = NULL;
int num_clients;
int thread_num;
void * client_handler(void * cl)
{
int * client = (int *)cl;
char * message = malloc(5000*sizeof(char));
printf("Connected: %d\n",*client);
int byte=1;
//recieve the message from clients
while(1)
{
byte=recv(*client, message , 5000 , 0);
if(byte< 0)
break;
//send message to all other clients
printf("%s\n",message);
printf("Recieved bytes:%d\n",byte);
memset(message, 0, 5000);
/*for(i=0;i<num_clients;i++)
if(client_fd[i]!=*client)
send(*client , message , strlen(message),0);*/
}
printf("finished: %d\n",*client);
return NULL;
}
int main(int argc, char ** argv)
{
//get the port
int port = atoi(argv[1]);
//set up socket
int socket_fd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server,client;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
//bind
if(bind(socket_fd, (struct sockaddr*)&server,sizeof(server)) < 0 ){
perror("binding error\n");
exit(1);
}
//listen
if( listen(socket_fd, 10) <0){
perror("binding error\n");
exit(1);
}
//accept incoming connectionns
threads = malloc(10*sizeof(pthread_t));
client_fd = malloc(10*sizeof(int));
int i=0;
int c = sizeof(struct sockaddr_in);
while(1)
{
int c_fd = accept(socket_fd,(struct sockaddr *)&client, (socklen_t*)&c);
if(c_fd < 0)
printf("error");
client_fd[i]=c_fd;
pthread_create(&threads[i],NULL,client_handler,(void *)(&c_fd));
i++;
num_clients=i;
}
return 0;
}
Sending C-style strings with strlen(). Does not send the terminating null. Use strlen()+1
Ignoring the value returned by recv(). TCP is a streaming protocol that only transfers bytes/octets. It does not transfer anything more complex. recv() may return one byte of your chat line, all of your chat line, or anything in between. To transfer any message more complex than one byte, you need a protocol and you must handle it. Yours is 'chat lines are null-terminated strings', so you need to call recv() in a loop and, using the returned value, concatenate the bytes received until the null arrives.
Trying to printf non-strings with "%s". You must not attempt to print out the received data until you are sure that a null has been received.
I have a problem, I have a client server udp, in server side I need to access data from client side to control movement of the robot. For the experiment I use to print "oke" if the value of the data is 1.
here the code program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MYPORT 4950
#define MAXBUFLEN 100
int sockfd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
struct hostent *he;
int addr_len, numbytes;
char dt[30];
char buf[MAXBUFLEN];
int main()
{
printf("‐‐‐‐‐ PROGRAM CHATTING ‐‐‐‐‐\n");
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){
perror("socket");
exit(1); }
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(my_addr.sin_zero),'\0',8);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("bind");
exit(1); }
while(1){
addr_len = sizeof(struct sockaddr);
if((numbytes=recvfrom(sockfd,buf,MAXBUFLEN-1,0,(struct sockaddr *)&their_addr,&addr_len))==-1)
{
perror("recvfrom");
exit(1);}
buf[numbytes]='\0';
printf("%s : \"%s\"\n", inet_ntoa(their_addr.sin_addr), buf);
if (buf[0]==1)
{ printf("oke\n");}
printf("Me : ");
scanf("%s", dt);
if((numbytes=sendto(sockfd,dt,strlen(dt),0,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)))==-1)
{
perror("sendto");
exit(1);
}
}
close(sockfd);
return 0;
}
when I put "1" in client side the result is:
‐‐‐‐‐ PROGRAM CHATTING ‐‐‐‐‐
130.130.66.76 : "1"
Me :
even in the program there are:
if (buf[0]==1)
{ printf("oke\n");}
why the program cannot access to inside of if?
Try if (buf[0]=='1')
Number characters map to different ASCII values than their number, so, for example, '1'==49.