简体   繁体   中英

UNIX Domain socket programming in C, printing issue

I am having a printing issue with my server. I want there to be simultaneous printing when I have 2 or more clients active on terminals. However, I am only printing from one client at a time. Once I close a client, the other clients are free to write to the server. What can I do to fix my problem?

I have tried to fork the printing section, which I think didn't really do anything. (Just realized if I do this, then the select system call is a waste, i'd rather use the select system call) *edit

while(TRUE) {

    FD_ZERO(&readfds);

    FD_SET(socket1, &readfds);
    FD_SET(socket2, &readfds);
    FD_SET(socket3, &readfds);

    select(socket3+1, &readfds, NULL, NULL, NULL);

    //add socket1
    if(FD_ISSET(socket1, &readfds)) {
        if((client_socket1 = accept(socket1, NULL, NULL)) < 0) {
            perror("accept1");
            exit(EXIT_FAILURE);
        }
        printf("New Connection\n");

        puts("Welcome message1 sent successfully\n");
    }

    //add socket2
    if(FD_ISSET(socket2, &readfds)) {
        if((client_socket2 = accept(socket2, (struct sockaddr *)&addr2, (socklen_t*)&addr2)) < 0) {
            perror("accept2");
            exit(EXIT_FAILURE);
        }
        printf("New Connection\n");

        puts("Welcome message2 sent successfully\n");
    }

    //add socket 3
    if(FD_ISSET(socket3, &readfds)) {
        if((client_socket3 = accept(socket3, (struct sockaddr *)&addr3, (socklen_t*)&addr3)) < 0) {
            perror("accept3");
            exit(EXIT_FAILURE);
        }
        printf("New Connection\n");

        puts("Welcome message3 sent successfully\n");
    }

    //print from socket 3
    while( (ready = read(client_socket3, buffer, sizeof(buffer))) > 0) {
        printf("%s\n", buffer);
    }

    //print from socket 2
    while( (ready = read(client_socket2, buffer, sizeof(buffer))) > 0) {
        printf("%s\n", buffer);
    }

    //print from socket 1
    while( (ready = read(client_socket1, buffer, sizeof(buffer))) > 0) {
        printf("%s\n", buffer);
    }
}

You need to add your client sockets to the fd_set and select statement before attempting to read from them. Also, you should make all your sockets non-blocking. Otherwise, the read call will block until you get data.

Here's a quick fix that uses recv instead of read to read the sockets, but with the async flag of MSG_DONTWAIT.

I didn't see anywhere where you were closing your client sockets or handling errors properly. So I inserted some code as a hint. Also, it's never a good idea to "printf" a buffer of data from a socket directly. Because you never know if the data you received is null terminated. Always null terminate your buffer after you read the data off the socket.

Change this block of code:

//print from socket 3
while( (ready = read(client_socket3, buffer, sizeof(buffer))) > 0) {
    printf("%s\n", buffer);
}

To this:

while (1)
{
    int result;
    result = recv(client_socket3, buffer, sizeof(buffer)-1, MSG_DONTWAIT);
    if ((result == -1) && 
             ((errno == EAGAIN) || (errno==EWOULDBLOCK)) )
    {
        // no more data available, but could be available later
        // use the socket with "select" above to wait for more data
    }
    else if ((result == -1) || (result == 0))
    {
        // remote close or unrecoverable error
        close(client_socket3);
        client_socket3=-1;
    }
    else
    {
        // null terminate the buffer before printing
        buffer[result] = '\0';
        printf("%s\n", buffer);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM