linux - 非阻塞 Linux 服务器套接字

标签 linux nonblocking

我想创建一个始终在屏幕上打印“tick”的服务器套接字,如果一个客户端向该服务器发送数据,服务器将打印该数据。我使用非阻塞套接字,但它不起作用,服务器打印到屏幕“勾选”但无法从客户端接收数据。

服务器

int main(int argc, char *argv[]) {
    int server_sockfd, client_sockfd;
    sockaddr_un server_address;
    sockaddr_un client_address;
    int client_len;
    int res;

    /* remove old socket and create unnamed socket */
    unlink("server_socket");
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

    /* non-blocking socket */
    fcntl(server_sockfd, F_SETFL, O_NONBLOCK);

    /* name the socket */
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "server_socket");
    bind(server_sockfd, (sockaddr*)&server_address, sizeof(server_address));

    /* listen client */
    printf("server_waiting\n");
    listen(server_sockfd, 5);
    client_len = sizeof(client_address);
    client_sockfd = accept(server_sockfd, (sockaddr*)&client_address, (socklen_t*)&client_len);

    while(1) {
        char ch;
        res = recv(client_sockfd, &ch, 1, 0);
        if (res == -1) {
            printf("tick\n");
        }
        else {
            printf("received: %c\n", ch);
        }
    }    
}

客户

int main(int argc, char *argv[]) {
    int sock_fd;
    struct sockaddr_un address;
    int result;
    char ch = 'A';

    /* create socket for client */
    sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);

    /* name of socket as agreed with server */
    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "server_socket");

    result = connect(sock_fd, (sockaddr*) &address, sizeof(address));
    if (result == -1) {
            perror("fail\n");
            exit(1);
    }

    /* write via socket */
    send(sock_fd, &ch, 1, 0);
    close(sock_fd);
    exit(0);
}

最佳答案

您正在将列表套接字设置为非阻塞而不是接受的套接字。

按照您的代码逻辑,您确实希望等待 accept 调用,而不是 recv 调用

代替

/* non-blocking socket */
fcntl(server_sockfd, F_SETFL, O_NONBLOCK);

删除它,而是将 fcntl 调用添加到您从 accept 调用返回的套接字中,例如

client_sockfd = accept(....);
int flags = fcntl(client_sockfd, F_GETFL, 0);
fcntl(client_sockfd, F_SETFL, flags | O_NONBLOCK);

acceptfcntl 可能会失败,因此您应该检查生产代码中的失败。

关于linux - 非阻塞 Linux 服务器套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44081430/

相关文章:

linux - 在启动之前将文件复制到 Docker 容器

c - Linux - 为什么自定义系统调用不能正常使用负数?

c - 当使用 `send` 调用 `send` 有未决数据时,调用 `MSG_MORE` 失败时会发生什么情况?

java - 异步数据库库是如何实现的?

linux - Shell 脚本 - help-me 列出文件和子目录

linux - recvfrom 失败,错误 11

perl - Perl 中的非阻塞/异步执行

multithreading - 'asynchronous', 'non-blocking'和 'concurrent'相互暗示吗?

c - 非阻塞读永不返回

bash - 当特定子进程终止时,如何在 bash 脚本中接收通知?