0

I am making a socket server with multiple clients in C Language.
To handle accesses of clients, function fork() was used in a server.

I made the source code that the children processes received each string from clients, and a parent process concatenate the strings to one string.

To send string to parent process, function pipe() was also used.

But clients closed file description before sending a concatenated string from server.

I wrote code that function write must be executed after concatenating strings.

How can i send to every clients with all concatenated strings?

enter image description here

the clients had input two and three was already closed.

Server Code

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

#define MAXLINE 1024
#define PORTNUM 3600

int main(int argc, char **argv)
{
    int p1[2];
    int p2[2];

    pipe(p1);
    pipe(p2);
    int index = 0;
    char channel[100];
    char full_str[MAXLINE];
    char recv[MAXLINE];

    int listen_fd, client_fd;
    pid_t pid;
    socklen_t addrlen;
    int readn;
    char buf[MAXLINE];
    struct sockaddr_in client_addr, server_addr;

    if( (listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        return 1;
    }
    memset((void *)&server_addr, 0x00, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORTNUM);

    if(bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) ==-1)
    {
        perror("bind error");
        return 1;
    }
    if(listen(listen_fd, 5) == -1)
    {
        perror("listen error");
        return 1;
    }

    signal(SIGCHLD, SIG_IGN);
    while(1)
    {
        addrlen = sizeof(client_addr);
        client_fd = accept(listen_fd,
            (struct sockaddr *)&client_addr, &addrlen);
        if(client_fd == -1)
        {
            printf("accept error\n");
            break;
        }
        pid = fork();
        if(pid == 0)
        {
            close( listen_fd );
            memset(buf, 0x00, MAXLINE);
            while((readn = read(client_fd, buf, MAXLINE)) > 0)
            {
                printf("Read Data %s(%d) : %s", inet_ntoa(client_addr.sin_addr), client_addr.sin_port, buf);

                close(p1[0]);
                write(p1[1], buf, sizeof(buf)+1);

                close(p2[1]);
                read(p2[0], recv, MAXLINE);

                if(strlen(recv) != 0) {
                    write(client_fd, buf, strlen(buf));
                }

                memset(buf, 0x00, MAXLINE);
            }
            close(client_fd);
            return 0;
        }
        else if( pid > 0) {
            close(p1[1])
            read(p1[0], channel, 100);
            strcat(full_str, channel)

            index++;

            if(index >= 3) {
                close(p2[0]);
                write(p2[1], full_str, MAXLINE);
            }
            close(client_fd);
        }
    }
    return 0;
}

Client Code

#include <sys/socket.h>  
#include <arpa/inet.h>   
#include <sys/stat.h>
#include <stdio.h>      
#include <string.h>     
#include <unistd.h>     

#define MAXLINE    1024

int main(int argc, char **argv)
{
    struct sockaddr_in serveraddr;
    int server_sockfd;
    int client_len;
    char buf[MAXLINE];

    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
    {
        perror("error :");
        return 1;
    }

    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serveraddr.sin_port = htons(3600);

    client_len = sizeof(serveraddr);

    if (connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len)  == -1)
    {
        perror("connect error :");
        return 1;
    }

    memset(buf, 0x00, MAXLINE);
    read(0, buf, MAXLINE); 
    if (write(server_sockfd, buf, MAXLINE) <= 0)    {
        perror("write error : ");
        return 1;
    }
    memset(buf, 0x00, MAXLINE);
    if (read(server_sockfd, buf, MAXLINE) <= 0)
    {
        perror("read error : ");
        return 1;
    }
    printf("read : %s", buf);
    close(server_sockfd);
    return 0;
}

QuavoHuncho
  • 51
  • 2
  • 4
  • Can you please provide the desired output? what is expected on the client side? – Uriya Harpeness Nov 03 '20 at 12:27
  • @UriyaHarpeness If i input one, two, three in each clients, the server send to all clients "onetwothree". – QuavoHuncho Nov 03 '20 at 12:32
  • the memory (`full_str`) is not shared between processes, look at this question to see how you can solve this: https://stackoverflow.com/questions/13274786/how-to-share-memory-between-processes-created-by-fork. – Uriya Harpeness Nov 03 '20 at 15:17
  • Check (and print for debugging) return values of every call. You do realise you're sending a bunch of `\0\0\0...` from clients? Not sure that's expected, but it's odd because there are some assumption on data being strings. – domen Nov 03 '20 at 15:17
  • `write(client_fd, buf, strlen(buf));` just echoes the client input. Did you mean `write(client_fd, recv, strlen(buf));`? – user58697 Nov 03 '20 at 21:40

0 Answers0