c - C 中的 UNIX 域套接字编程,打印问题

标签 c sockets unix-socket

我的服务器出现打印问题。当终端上有 2 个或更多客户端处于事件状态时,我希望同时进行打印。但是,我一次只从一个客户打印。一旦我关闭一个客户端,其他客户端就可以自由地写入服务器。我该怎么做才能解决我的问题?

我尝试过 fork 打印部分,但我认为它并没有真正做任何事情。 (刚刚意识到如果我这样做,那么选择系统调用就是一种浪费,我宁愿使用选择系统调用)*编辑

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);
    }
}

最佳答案

在尝试读取之前,您需要将客户端套接字添加到 fd_setselect 语句中。此外,您应该使所有套接字都成为非阻塞的。否则,read 调用将阻塞,直到您获得数据。

这是一个快速修复,它使用 recv 而不是 read 来读取套接字,但带有 MSG_DONTWAIT 的异步标志。

我没有看到您关闭客户端套接字或正确处理错误的任何地方。所以我插入了一些代码作为提示。此外,直接从套接字“打印”数据缓冲区绝不是一个好主意。因为您永远不知道您收到的数据是否以空值终止。从套接字读取数据后,始终以 null 终止缓冲区。

更改此代码块:

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

对此:

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);
    }
}

关于c - C 中的 UNIX 域套接字编程,打印问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30146760/

相关文章:

c - 在 WM_MOUSEMOVE 中绘图

c - 为什么我会遇到段错误(多维数组 C)

javascript - 如何在 Sails.js v0.11 中触发自定义套接字事件?

c - kernel_recvmsg 有时会得到错误的数据

c++ - 在 C/Unix 中监听 IP 子网的套接字

java - 在带有选择器的非阻塞模式下将 Java NIO 与 Unix 域套接字一起使用

c - malloc 为 List 分配内存

linux - errno.h 套接字/连接错误分类

c# - 关于 C# 中 RCON 协议(protocol)实现的令人难以置信的问题

c - OpenCV中像素邻域差异的高效算法