简体   繁体   English

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

[英]Weird order after select() (with FD_SET())

I am developing a multi-client Unix Domain Socket to transfer data through multiple processes. 我正在开发一个多客户端Unix域套接字,以通过多个进程传输数据。 I found some code that implements chat between every client and stuff but I want that once a client send something to the server, the server reply back and the client disconnect. 我找到了一些实现每个客户端与其他对象之间的聊天的代码,但我希望一旦客户端将某些内容发送到服务器,服务器就会回复并客户端断开连接。

Having that said, I don't want while(fgets()) but I want (on client side): 话虽如此,我不希望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);
}

In this order, it works if I do everything after connect() twice (with a loop) but I want to do it only once. 按此顺序,如果我在connect()之后执行两次所有操作(带有循环),但我只想执行一次,则可以使用。 Without this loop, my server (which is a daemon) crash and I don't know why. 没有这个循环,我的服务器(这是一个守护程序)崩溃,我也不知道为什么。

Furthermore, I added printf() from the code above to understand how it works: 此外,我从上面的代码中添加了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 */
}
(...)

And I have this output: 我有这个输出:

before select
"input to fgets"
after select

And I don't understand why I have the input BEFORE "after select". 而且我不明白为什么在“选择后”之前需要输入。 It doesn't make any sense to me since I call fgets() after printf() . 这对我来说没有任何意义,因为我在printf()之后调用fgets() printf()

I hope this is understandable enough. 我希望这是可以理解的。 What's wrong with my code ? 我的代码有什么问题? Did I miss something ? 我错过了什么 ?

The first time through, you call select() before the server has responded. 第一次,您需要在服务器响应之前调用select() The result is that sockfd won't be ready for reading. 结果是sockfd将无法阅读。

In your case, the client might not need select() on the sockfd . 在您的情况下,客户端可能不需要sockfd上的select() You know that if you wrote something to the server you want to wait for the reply, right? 您知道,如果您向服务器写了一些内容,则想等待回复,对吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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