Reputation: 67
I have a simple tcp based client and server written in c, but once I establish a connection after the server sends a message back to the client, the connection stops working. Could you help me fix this - I would like the server to continue receiving/ sending messages to the client.
Code:
Server.c
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#define port 5000
#define buf 512
void answer(int);
int main(int argc, char *argv[]){
int sock = socket(AF_INET, SOCK_STREAM, 0);
int portid;
int backlog = 10;
struct sockaddr_in addr;
char BUFF[buf];
int n;
int received = 0;
int connfd;
if(sock == -1){
perror("socket error");
exit(errno);
}
memset(&addr,0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) == -1){
perror("bind error");
exit(errno);
}
if(listen(sock, backlog) == -1){
perror("listen error");
exit(errno);
}
listen(sock, 5);
struct sockaddr_in cliaddr;
//struct sockaddr_in addr;
int cliaddr_len = sizeof(cliaddr);
while(1){
connfd = accept(sock, (struct sockaddr*)&cliaddr,&cliaddr_len);
if(connfd == -1){
perror("error connfd");
exit(errno);
}
portid = fork();
if(portid<0)
perror("error on fork");
if(portid ==0){
close(sock);
answer(connfd);
exit(0);
}
//close(sock);
}
close(connfd);
return 0;
//close(sock);
//return 0;
}
void answer(int connfd){
int n;
char BUFF[buf];
memset(BUFF,buf,buf);
n = read(connfd,BUFF,buf);
printf("connected: %s",BUFF);
//received = 1;
//memset(BUFF,0,buf);
printf("please enter your message: ");
memset(BUFF,0,buf);
fgets(BUFF,buf, stdin);
n = write(connfd, BUFF,strlen(BUFF));
if(n<0) err("writing to socket problem");
}
Upvotes: 0
Views: 247
Reputation: 729
You are reading the data in your child, so once the child is done the program exits, so try to read in the parent and send the data along to the child.
Upvotes: 0
Reputation: 4411
This is because you recv()
data just one time. Use a loop to receive until the client disconnects.
while ((n = read(connfd,BUFF,buf))
{
printf("connected: %s",BUFF);
//received = 1;
//memset(BUFF,0,buf);
printf("please enter your message: ");
memset(BUFF,0,buf);
fgets(BUFF,buf, stdin);
n = write(connfd, BUFF,strlen(BUFF));
if(n<0) err("writing to socket problem");
}
Upvotes: 0
Reputation: 39807
Your server is calling fork, then if(portid ==0){...get and send message...}
, then it loops back to the top of the loop where it tries to accept()
--- not the job of the child, but the child is trying to do that anyway.
Refactor your code to do what you want. Break it into smaller parts that are simple for you to inspect so you can see things like this.
Upvotes: 2