接受多个连续连接到套接字

7
我有一个监听器,将任意数据(HTTP请求)传递给网络套接字,然后通过TCP传输。这对于第一个请求很好用,但是监听器不接受后续新请求。
我的问题是:
如果我有sock=accept(listener,(struct addr *)&sin, &sinlen);,那么基于套接字函数的参考,监听器套接字仍然保持打开状态,我应该能够为后续请求重新调用accept()。这是正确的吗?如果是,比我更熟悉套接字编程的人可以解释一下这段代码的实现方式吗?
3个回答

12

是的,你可以在监听套接字上多次调用accept()。为了为多个客户端提供服务,你需要避免阻塞I/O——也就是说,你不能只从套接字中读取并阻塞直到数据到达。有两种方法:你可以在它自己的线程中为每个客户端提供服务(或在UNIX系统上使用fork()以使用自己的进程),或者你可以使用select()select()函数是一种检查一组文件描述符中是否有可用数据的方法。它适用于UNIX和Windows操作系统。


6
你忘了一个选项,你也可以使用分叉(fork)的方式来处理事情,这是处理事情的传统Unix方式。 - Robert S. Barnes
如果您使用单独的线程,则无需避免阻塞I/O。 - user207421

7
这是一段来自Beej的网络编程指南的简单示例。
while(1) {  // main accept() loop
    sin_size = sizeof their_addr;
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    if (new_fd == -1) {
        perror("accept");
        continue;
    }

    inet_ntop(their_addr.ss_family,
        get_in_addr((struct sockaddr *)&their_addr),
        s, sizeof s);
    printf("server: got connection from %s\n", s);

    if (!fork()) { // this is the child process
        close(sockfd); // child doesn't need the listener
        if (send(new_fd, "Hello, world!", 13, 0) == -1)
            perror("send");
        close(new_fd);
        exit(0);
    }
    close(new_fd);  // parent doesn't need this
}

孩子进程在fork()后异步处理与父进程中accept()之外的其他连接的通信。

仅仅提供一个链接并不是一个答案。 - user207421
请避免仅提供链接的答案。那些“几乎只是一个指向外部网站的链接”的答案可能会被删除。 - Quentin
1
是的,人们自然而然地加入了猎巫行动。 - Nikolai Fetissov
2
我已经添加了来自该网站最相关的部分;那就是如何使链接唯一的答案不被关闭。 - Donal Fellows
1
谢谢,Donal。这样做确实有道理,而不是简单地投反对票。 - Nikolai Fetissov

0

是的,你有正确的一般想法。

虽然我的C套接字编程有点生疏,但在服务器套接字上调用accept会设置回到套接字客户端的通信通道。在未来的连接尝试中调用accept将设置多个套接字通道。

这意味着应该注意不要用特定连接的数据覆盖单个共享结构,但听起来你不太可能犯这种错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接