Search code examples
csocketsposix

C posix sockets, can't send data from client to server


I want to make a client and connect it to a server. I know that client process starts running before server so I do connection in infinite loop until it will be accept. Then I want to enter messages to client and send them to server, which will print them on screen. I removed all error detection from code to make it shorter, I know they have to be there. I am trying to do it like this, but server receives nothing and client can't do second connection.

Server

int main(int argc, char *argv[])
{
    int sockfd, newsockfd;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(5000);
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    listen(sockfd, 5);
    clilen = sizeof(cli_addr);
    while (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0)
    {
        read(newsockfd, buffer, 255);
        close(newsockfd);
    }
    close(sockfd);
    return 0;
}

Client

int main(int argc, char *argv[])
    {
    int sockfd;
    struct sockaddr_in serv_addr;

    char buffer[256];
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(5000);
    while (1) {
        while ((connect(sockfd,(struct sockaddr *)  &serv_addr,sizeof(serv_addr)) < 0)) {
           printf("trying to connect\n");
           sleep(1);
        }
        printf("connected\nplease, enter a message\n");
        scanf("%s", buffer);
        write(sockfd, buffer, strlen(buffer));
    }
    close(sockfd);
    return 0;
}

Solution

  • I don't know just how you've compiled your code but if you had set up the warning flag (-Wall in gcc) you would have gotten this warning

    server.c: In function ‘main’:
    server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
    

    Acting by it, I changed, this ..

    if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
    

    To .. (notice the extra parentheses)

    if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) {
    

    I got no more additional warnings, and the server caught the client's message.

    Here is the server I ran while debugging this (This is basically your code with slight alterations)

    int sockfd, newsockfd;
    socklen_t clilen;
    char buffer[256];
    int nbytes = 0;
    struct sockaddr_in serv_addr, cli_addr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    serv_addr.sin_family = AF_INET;
    //serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(5007);
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    
    
    if (listen(sockfd, 5) <0) { }
    
    clilen = sizeof(cli_addr);
    if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) { 
    
        while ((nbytes = read(newsockfd, buffer, sizeof(buffer)))<0) {
            sleep(1);
        }
    
        printf("client sent: %s", buffer);
    }
    close(newsockfd);
    close(sockfd);
    return 0;