Chat client in c - c

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.

Related

Why my simple C server exits when the client closes connection?

#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <strings.h> /* bzero(), bcopy() */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
int main(int argc, char **argv){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in my_addr;
bzero(&my_addr,sizeof my_addr);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(9999);
my_addr.sin_addr.s_addr = INADDR_ANY;
int res;
res = bind(sockfd,(struct sockaddr *)&my_addr,sizeof (struct sockaddr_in));
res = listen(sockfd,5);
while (1) { // shouldn't this while cycle "keep alive" the server to wait for new clients?
struct sockaddr_in cli_addr;
bzero(&cli_addr,sizeof cli_addr);
socklen_t cli_size = sizeof (struct sockaddr_in);
int clisockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&cli_size);
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",sockfd,b_recv);
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}
}
}
If I test my server with netcat, if I close netcat the server exits. Why? Shouldn't the external while loop keep it alive? Why and how can I avoid that the server closes?
If you check closely the server will be terminated with a SIGPIPE signal when you close the connection from the client-side.
It happens because you don't check for closed-connection events, and attempt to write to the closed connection.
When recv return 0 you should not attempt to write to the connected socket. Instead you should close the socket and break out of the inner recv/send loop.
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",clisockfd,b_recv); // Print the connection socket instead
if (b_recv <= 0) {
// Error or closed connection
close(clisockfd);
break; // Go back to the outer loop, wait for new connections
}
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}

I got some strange word 'Received: 艎��' in socket program

I wrote a server program and a client program that communicate with sockets on linux ubuntu. The client program outputs Received: 艎��
This my server code:
/*** tcp_server.c ***/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
int sock_fd, new_fd, bytes;
struct sockaddr_in seraddr, cliaddr;
char data[1024];
socklen_t cli_addr_size;
cli_addr_size = sizeof(cliaddr);
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY : It received Network Interface that connected server defined interface, htonl :
seraddr.sin_port = htons(5050);
bind(sock_fd, (struct sockaddr *)&seraddr, sizeof(seraddr));
listen(sock_fd, 10);
while (1) {
new_fd = accept(sock_fd, (struct sockaddr *)&cliaddr, &cli_addr_size);
bytes = recv(new_fd, data, 1024, 0);
send(new_fd, data, bytes, 0);
close(new_fd);
}
close(sock_fd);
}
My client code is:
/*** tcp_client.c ***/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(int argc, char *argv[]) {
int sock_fd, bytes;
struct sockaddr_in ser_addr;
char *snddata, rcvdata[1024];
snddata = argv[2];
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
memset(&ser_addr, 0,sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_addr.s_addr = inet_addr(argv[1]); // INADDR_ANY : It received Network Interface that connected server defined interface, htonl :
ser_addr.sin_port = htons(5050);
connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
send(sock_fd, snddata, strlen(snddata), 0);
printf("Received: ");
bytes = recv(sock_fd, rcvdata, 1024, 0);
rcvdata[bytes] = '\0';
printf("%s\n", rcvdata);
close(sock_fd);
}
First I got an error for argument 3 of accept, then I changed
new_fd = accept(sock_fd, (struct sockaddr *)&cliaddr, sizeof(cliaddr);
But It still produces this strange word.
Try to change your send() and receive() functions so that you have full control over how much and which byte you send from the buffer (data[1024]) like in this thread : C socket: recv and send all data and also see Beej's Guide to Network Programming (http://beej.us/guide/bgnet/)
Also make sure that you initialize your data buffers:
data[1024] = "";
rcvdata[1024] = "";
or
data[1024];
data[0] = '\0';
rcvdata[1024];
rcvdata[0] = '\0';
, background is in this thread : Why I am getting this unusually symbols by printing char string

I am trying to echo the string from the server to the client with UDP sockets but it is failing?

I have made one server and one client communicating through UDP sockets. The work that I am trying to do is that client will pass a string in the arguments and that string will be send to the server using UDP sockets. After receiving the string server will again echo(send) the string back to the client.Below are the codes for both:
code for echoClient.c :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXLINE 4096
int main(int argc, char const *argv[])
{
int sockfd;
struct sockaddr_in servAddr;
char sendLine[MAXLINE],recvLine[MAXLINE];
if(argc!=3)
{
printf("echoClient <Ip addr. of the server> <String to be echoed> \n");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
printf("Error in creating the socket\n");
exit(2);
}
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(6565); // setting up the port
servAddr.sin_addr.s_addr = inet_addr(argv[1]); // using the given ip address of the server
printf("%s\n", argv[2]);
if((sendto(sockfd,(const char *)argv[2],strlen(argv[2]), MSG_CONFIRM,(struct sockaddr *) &servAddr, sizeof(servAddr))!=-1))
{
printf("data is sent to the server\n");
}
else
{
printf("can't send the data to the server\n");
exit(3);
}
int n = recvfrom(sockfd,(char * ) recvLine,MAXLINE,0,(struct sockaddr * )&servAddr,sizeof(servAddr));
if(n==-1)
{
printf("Can't receive the data from the server\n");
exit(4);
}
recvLine[n] = '\0'; // to terminate the received string
printf("%s\n",recvLine);
return 0;
}
code for echoServer.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define MAXLINE 4096
int main(int argc, char const *argv[])
{
int sockfd;
struct sockaddr_in servAddr,clientAddr;
char sendLine[MAXLINE],recvLine[MAXLINE];
if(argc!=1)
{
printf("echoServer\n");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
printf("Error in creating the socket\n");
exit(2);
}
memset(&servAddr,0,sizeof(servAddr));
memset(&clientAddr,0,sizeof(clientAddr));
// filling the details of the server ip and port
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(6565);
servAddr.sin_addr.s_addr = INADDR_ANY; // using the given ip address of the server
if(bind(sockfd,(struct sockaddr * )&servAddr,sizeof(servAddr))<0)
{
printf("Binding of the socket failed\n");
exit(1);
}
printf("Server is Up... Waiting for the client...\n");
int len;
int n = recvfrom(sockfd,(char *) recvLine,MAXLINE,MSG_WAITALL,(struct sockaddr * )&clientAddr,&len);
if(n==-1)
{
printf("can't get the message from the client\n");
exit(2);
}
recvLine[n] = '\0';
printf("Message received from the client is %s\n",recvLine);
if(sendto(sockfd,(char *) recvLine,n,MSG_CONFIRM,(struct sockaddr *)&clientAddr,len)<0)
{
printf("can't send the message to the client\n");
exit(3);
}
return 0;
}
Now the actual problen is that when I am executing the above codes client is able to send the string to the server but server is unable to send the string back to the client.Server gives the error can't send the message to the client.
I am not able to figure out the error which is stopping the server to send the message to the client.Please help me with this.
I am running the echoClient.c with the command :
./a.out 127.0.0.1 hellofromclientside
In the server, you overlooked that the argument len to recvfrom() is a value-result argument, which before the call you have to initialize to the size of the clientAddr in order to get this address, so change
int len;
to
int len = sizeof clientAddr;
Similarly in the client, change
int n = recvfrom(sockfd,(char * ) recvLine,MAXLINE,0,(struct sockaddr * )&servAddr,sizeof(servAddr));
to
int len = sizeof servAddr;
int n = recvfrom(sockfd, recvLine, MAXLINE, 0, (struct sockaddr *)&servAddr, &len);

Invalid Argument from sendto() Socket Program in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm trying to make a simple client-server API to be used for two of my machines. I made this simple program that uses the functions I made to test it. For some reason my client sends a message just fine, but my server can't (however, it receives the message from the client).
Server side output:
host name: my_host
Our port number is: 34440
Client msg: Client msg
Send failed: Invalid argument
Message from Server sent to Client
Client side output:
Connection established with server...
Message from Client sent to Server
Server side:
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include "my_socket.h"
int main() {
server_init();
char *msg = "Server msg";
char buffer[100];
int n = read_from_client((char *)buffer);
buffer[n] = '\0';
printf("Client msg: %s\n", buffer);
write_to_client((char *)msg);
printf("Message from Server sent to Client \n");
return 0;
}
Client Side:
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include "my_socket.h"
int main() {
client_init();
char *msg = "Client msg";
char buffer[100];
write_to_server((char*)msg);
printf("Message from Client sent to Server \n");
int n = read_from_server((char *)buffer);
buffer[n] = '\0';
printf("Server msg: %s\n", buffer);
close_socket();
return 0;
}
my_socket.c:
#include "my_socket.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
int sockfd1;
int sockfd2;
int MAX_BUFF = 1024;
struct sockaddr_in server;
struct sockaddr_in client;
struct hostent *host;
ssize_t write_to_server(const void *buffer){
int bytes_sent, server_size = sizeof(server), buf_len = strlen(buffer);
if ((bytes_sent = sendto(sockfd2, buffer, buf_len, 0,
(const struct sockaddr *)&server, server_size)) < 0){
perror("Send failed");
}
return bytes_sent;
}
ssize_t write_to_client(const void *buffer){
int bytes_sent, client_size = sizeof(client), buf_len = strlen(buffer);
if ((bytes_sent = sendto(sockfd1, buffer, buf_len, 0,
(const struct sockaddr *)&client, client_size)) < 0){
perror("Send failed");
}
return bytes_sent;
}
int read_from_server(void *buffer){
int bytes_rcv, len;
if ((bytes_rcv = recvfrom(sockfd2, buffer, MAX_BUFF, MSG_WAITALL,
(struct sockaddr *)&server, &len)) < 0){
perror("Read failed");
}
return bytes_rcv;
}
int read_from_client(void *buffer){
int bytes_rcv, len;
if ((bytes_rcv = recvfrom(sockfd1, buffer, MAX_BUFF, MSG_WAITALL,
(struct sockaddr *)&client, &len)) < 0){
perror("Read failed");
}
return bytes_rcv;
}
void close_socket() {
close(sockfd1);
close(sockfd2);
}
void server_init(){
if ( (sockfd1 = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
}
char name[1024];
name[1023] = '\0';
gethostname(name, 1023);
printf("host name: %s \n", name);
host = gethostbyname("my_host");
if(host == NULL){
perror("Host is null");
exit(0);
}
bzero((char *)&server, sizeof(server));
bzero((char *)&client, sizeof(client));
server.sin_family = AF_INET;
bcopy((char *)host->h_addr,
(char *)&server.sin_addr.s_addr, host->h_length);
//server.sin_port = 0;
server.sin_port = htons(34440);
if ( (bind(sockfd1, (struct sockaddr *)&server, sizeof(server) ) ) < 0 ){
perror("bind failed");
}
socklen_t len = sizeof(server);
if (getsockname(sockfd1, (struct sockaddr *)&server, &len) == -1){
perror("getsockname");
}else{
printf("Our port number is: %d\n", ntohs(server.sin_port));
}
}
void client_init(){
if ( (sockfd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
}
host = gethostbyname("my_host");
if(host == NULL){
perror("Host is null");
exit(0);
}
bzero((char *)&server, sizeof(server));
server.sin_family = AF_INET;
bcopy((char *)host->h_addr,
(char *)&server.sin_addr.s_addr, host->h_length);
//server.sin_port = 0;
server.sin_port = htons(34440);
if(connect(sockfd2, (struct sockaddr *)&server, sizeof(server)) == 0){
printf("Connection established with server...\n");
}
}
my_socket.h:
#ifndef MY_SOCKET
#define MY_SOCKET
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
extern int sockfd1;
extern int sockfd2;
extern int MAX_BUFF;
extern struct sockaddr_in server;
extern struct sockaddr_in client;
extern struct hostent *host;
// Send a message over the socket
ssize_t write_to_server(const void *buffer);
ssize_t write_to_client(const void *buffer);
// Blocks until told it's ready; receives bytes from socket
int read_from_server(void *buffer);
int read_from_client(void *buffer);
// Close the socket
void close_socket();
void server_init();
void client_init();
#endif
Any advice or criticism is welcome. Thanks in advance.
At least one issue is that you are not initializing the len variable in read_from_client. The manual page for recvfrom says, in part (emphasis added):
... addrlen is a value-result argument. Before the call, it should be initialized to the size of the buffer associated with src_addr. Upon return, addrlen is updated to contain the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.
That means that, as an uninitialized stack variable, len has an indeterminate value. Probably zero, but at least something smaller than sizeof(struct sockaddr_in). As a result, client is not getting filled in correctly by the recvfrom.
Just before the recvfrom, you should initialize it with:
len = sizeof(client);
On the client side, write_to_server and read_from_server need not use recvfrom and sendto as you have already done a connect on the socket. They can simply use recv and send since the remote socket endpoint is already established by the connect. I believe the address is simply ignored for a connected socket, but I cannot find where that is documented right now.
(In any case, if you do continue to use recvfrom on the client side, you should make the same len initialization there.)

Server not able to receive message from client

I am using Ubuntu 12.05.I have been trying to implement Stop and wait protocol through C socket programming.I have created two programs,one featuring the server and other one the client. Expected working of the code is explained through comments
serversocket.c
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc,char *argv[])
{
int listenfd = 0,qlength=10,connfd = 0,t=5;
int n;
struct sockaddr_in serv;
struct sockaddr_in dest;
socklen_t socksize = sizeof(struct sockaddr_in);
char sendBuff[1024]="hi\n";
//time_t ticks;
listenfd = socket(AF_INET,SOCK_STREAM,0); //socket for listening to connection requests
memset(&serv,'0',sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port=htons(5000);
bind(listenfd,(struct sockaddr *)&serv,sizeof(serv)); //binding the socket to a port
listen(listenfd,2);
connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize); //another socket for sending and receiving on the previously built socket
while(connfd){
printf("Incoming connection from %s-sending a hi...\n",inet_ntoa(dest.sin_addr));
send(connfd,sendBuff,strlen(sendBuff),0); //at first my server sends a hi
sleep(3);
n=recv(connfd,sendBuff,1024,0); //if hi received by the client,then server should receive "Message Received" from the client
sendBuff[n]='\0';
printf("%s",sendBuff);
connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize); }
return 0;
}
clientsocket.c
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0,m=2;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while(m--){ //m is 2 initially,I want that sending and receiving should be done 2 times
n = recv(sockfd,recvBuff,1024,0);
recvBuff[n]='\0'; //"hi" is received
printf("%s",recvBuff);
if(recvBuff=="hi\n")
send(sockfd,"Message Received",strlen("Message Received\n"),0);} //sending "Message received"
return 0;
}
Now sending messages from server to client works fine, but client to server(Message received) is creating problems.Neither it is giving an error, nor correct results,it just gives a blank screen.
You cannot compare strings using the "==" operator.
You need to use strcmp()
So....
if( strcmp( recvBuff, "hi\n" ) == 0 )
send(sockfd,"Message Received",strlen("Message Received\n"),0);
else
printf( "[%s] != [hi\n]\n", recvBuff );
Basically, you have three different issue in your code:
the string comparison (fixed by K Scott Piel).
The print of the received message are not coming out. You need to add '\n' in all your printf functions.
This is the most important issue: after the first communication between the server and the client, you are calling the accept function in the server code. From the man accept page, we can read
The accept() function shall extract the first connection on the
queue of pending connections, create a new socket with the same socket
type protocol and address family as the specified socket, and allocate
a new file descriptor for that socket.
So, after the first communication, your server is waiting for a new connection and your client is waiting for a message from the server. The second communication will never happen.
To solve this issue, you can use fork() API.
Here is a fix proposal using the fork():
clientsocket.c
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0,m=2;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
//m is 2 initially,I want that sending and receiving should be done 2 times
while(m--)
{
printf("Waiting from the server ...\n");
n = recv(sockfd,recvBuff,1024,0);
recvBuff[n]= '\0'; //"hi" is received
printf("%s\n", recvBuff);
if(!strncmp(recvBuff, "hi\n", strlen("hi\n")))
{
printf("Send ACK\n");
n = send(sockfd,"Message Received",strlen("Message Received\n"),0);
printf("%d Sent ... \n", n);
}
} //sending "Message received"
return 0;
}
serversocket.c
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc,char *argv[])
{
int listenfd = 0,qlength=10,connfd = 0,t=5;
int n;
struct sockaddr_in serv;
struct sockaddr_in dest;
socklen_t socksize = sizeof(struct sockaddr_in);
char sendBuff[1024]="hi\n";
pid_t pid;
int m = 2;
//time_t ticks;
listenfd = socket(AF_INET,SOCK_STREAM,0); //socket for listening to connection requests
memset(&serv,'0',sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port=htons(5000);
bind(listenfd,(struct sockaddr *)&serv,sizeof(serv)); //binding the socket to a port
printf("Server started ...\n");
listen(listenfd,2);
connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize); //another socket for sending and receiving on the previously built socket
while(connfd > 0)
{
printf("Incoming connection from %s-sending a hi...\n",inet_ntoa(dest.sin_addr));
pid = fork();
if(pid) {
/* shall continue to listen to new client */
printf("Parent shall continue listening ... \n");
connfd=accept(listenfd,(struct sockaddr *)&dest,&socksize);
} else {
printf("Chlid process: Communication with the client ... \n");
while(m--)
{
printf("try %d - Sending %s ... \n", m, sendBuff);
send(connfd,sendBuff,strlen(sendBuff),0); //at first my server sends a hi
sleep(3);
n=recv(connfd, sendBuff, 1024, 0); //if hi received by the client,then server should receive "Message Received" from the client
sendBuff[n]='\0';
printf("Data received: [%s]\n", sendBuff); /* need to add '\n' so the print will be displayed */
strcpy(sendBuff, "hi\n");
}
printf("Child process will exit\n");
return 0;
}
}
return 0;
}

Resources