【问题标题】:Reading consecutive messages读取连续消息
【发布时间】:2018-10-23 14:51:01
【问题描述】:

我创建了一个服务器并尝试监听特定端口。当我使用 netcat 向此特定端口发送消息时,我成功读取了第一条消息,其中

read(fd_client_serv, buf, sizeof(buf));

系统调用。之后,发送的任何消息都不会被打印。为什么会这样?

这是我的代码:

void start_server(void)
{

    int fd_serv, fd_client_serv, bytes_read;
    struct sockaddr_in client_serv_addr;
    char buf[2048];

    socklen_t sin_len_serv = sizeof(client_serv_addr);

    fd_serv = initialize_server(get_serving_port());
    fd_set_blocking(fd_serv, 0);

    while(1)
    {
        fd_client_serv = accept(fd_serv, (struct sockaddr *) &client_serv_addr, &sin_len_serv);

        puts("HA!!! you cannot block me!!!");
        sleep(2);
        memset(buf, 0, sizeof(buf));
        write(fd_client_serv, "thank you for answering", 30);
        bytes_read = read(fd_client_serv, buf, sizeof(buf));
        printf("%d\n", bytes_read);
        fflush(stdout);
        printf("%s\n", buf);
    }
}


int initialize_server(int port)
{

    struct sockaddr_in server_addr;

    int fd_temp;

    int on = 1;

    fd_temp = socket(AF_INET, SOCK_STREAM, 0);
    if (fd_temp < 0)
    {
        perror("socket");
        exit(1);
    }
    setsockopt(fd_temp, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);

    if (bind(fd_temp,(struct sockaddr *) &server_addr, sizeof(server_addr)) == -1)
    {
        perror("bind");
        close(fd_temp);
        exit(1);
    }
    if (listen(fd_temp, 10) == -1)
    {
        perror("listen");
        close(fd_temp);
        exit(1);
    }
    return fd_temp;
}


int fd_set_blocking(int fd, int blocking)
{
    /* Save the current flags */
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1)
        return 0;

    if (blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;
    return fcntl(fd, F_SETFL, flags) != -1;
}

我刚刚注意到,如果我关闭 netcat(或 telnet)并启动一个新的,我可以再次阅读发送的第一条消息。但就是这样。

【问题讨论】:

    标签: c server message nonblocking


    【解决方案1】:

    accept() 接受新连接。因此,每次通过循环时,您都将 fd_client_serv 设置为新连接的套接字 id,从而放弃旧连接。 (“放弃”的意思是你再也不会read,因为你失去了它的id。你没有关闭它,但你已经忘记了它。)

    【讨论】:

    • 所以我必须以某种方式只重复我的read code 对吗?或者我应该将我的fd_client_serv 设置在while 循环之外?
    • 没错。 “不知何故” -> 把它放在一个循环中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 2015-08-21
    相关资源
    最近更新 更多