Petar Yordanov
Petar Yordanov

Reputation: 67

Client and server in C how to keep communication

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

Answers (3)

Trilok M
Trilok M

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

nouney
nouney

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

mah
mah

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

Related Questions