select()之后的奇怪顺序(使用FD_SET())

时间:2017-03-17 11:57:49

标签: c select unix-socket

我正在开发一个多客户端Unix域套接字,以通过多个进程传输数据。我找到了一些在每个客户端和东西之间实现聊天的代码,但是我希望一旦客户端向服务器发送内容,服务器回复并且客户端断开连接。

说完了,我不想while(fgets())但我想(在客户端):

int main() {
    int sockfd;
    struct sockaddr_un remote;
    fd_set readfds;
    char buf[1024];
    char buf2[1024];
    int len;

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);

    if(connect(sockfd, (struct sockaddr*)&remote, len) == -1)
        /* handle error */

    FD_ZERO(&readfds);
    FD_SET(0, &readfds);
    FD_SET(sockfd, &readfds);

    if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
        /* handle error */

    if(FD_ISSET(0, &readfds)) {
        fgets(buf, 1024, stdin);
        if(write(sockfd, buf, 1024) <= 0)
            /* handle error */
    }

    if(FD_ISSET(sockfd, &readfds)) {
        if(read(sockfd, &buf2, 1024) <= 0)
            /* handle error */
    }

    printf("%s\n", buf2);

    close(sockfd);
}

按照这个顺序,如果我在connect()之后执行两次(使用循环)但是我只想做一次,它就可以工作。没有这个循环,我的服务器(这是一个守护进程)崩溃,我不知道为什么。

此外,我在上面的代码中添加了printf()以了解其工作原理:

(...)
printf("before select\n");
fflush(stdout);

if(select(sockfd+1, &readfds, NULL, NULL, NULL) == -1)
    /* handle error */

printf("before select\n");
fflush(stdout);

if(FD_ISSET(0, &readfds)) {
    fgets(buf, 1024, stdin);
    if(write(sockfd, buf, 1024) <= 0)
        /* handle error */
}
(...)

我有这个输出:

before select
"input to fgets"
after select

在选择&#34;之后,我不明白为什么我在输入之后输入了#34;由于我在fgets()之后致电printf(),因此对我没有任何意义。

我希望这是可以理解的。 我的代码出了什么问题?我错过了什么吗?

1 个答案:

答案 0 :(得分:1)

第一次,在服务器响应之前调用select()。结果是sockfd无法准备好阅读。

在您的情况下,客户可能不需要select()上的sockfd。你知道如果你在服务器上写了一些东西,你想等待回复,对吗?