【问题标题】:Multi-clients on a server服务器上的多客户端
【发布时间】:2011-03-25 22:21:16
【问题描述】:

对于 C 中的应用程序,我需要响应多个客户端。

我使用如下代码设置连接,

    bind(...);
    listen(...);
    while(1){
        accept(...);//accept a client
        recv(...);//receive something
        send(...);//send something to client
        bzero(buf);//clear buffer
    }  

当我只有一个客户时,这很有效。其他客户端也可以连接到服务器,但尽管它们发出命令,但服务器不会响应在第一个客户端之后连接的客户端。我该如何解决这个问题?

【问题讨论】:

  • pollselect 也可以。如果数据应该在客户端之间共享(例如,在聊天服务器中),它会比线程更灵活,并且比分叉更容易使用。
  • @cHao 实际上,我尝试使用 select,但无法使其工作。能举个例子吗?

标签: c sockets client-server


【解决方案1】:

使用异步、非阻塞连接编写服务器。

您需要创建一个结构,而不是关于客户端的一组数据。结构的每个实例都保存每个客户端的数据。

代码看起来有点像:

socket(...)
fcntl(...) to mark O_NONBLOCK
bind(...)
listen(...)
create poll entry for server socket.
while(1) {
    poll(...)
    if( fds[server_slot].revents & POLLIN ) {
        accept(...)
        fcntl(...) mark O_NONBLOCK
        create poll and data array entries.
    }
    if( fds[i].revents & POLLIN ) {
        recv(...) into data[i]
        if connection i closed then clean up.
    }
    if( fds[i].revents & POLLOUT ) {
        send(...) pending info for data[i]
    }
 }

如果您的任何调用返回错误 EAGAIN 而不是成功,请不要惊慌。你稍后再试一次。即使民意调查声称套接字已准备好,也要为 EAGAIN 做好准备:这是一种很好的做法,而且更健壮。

【讨论】:

  • 您是否需要非阻塞套接字才能使用poll?如果不是,如果我们使用一个线程进行读/写,还有什么比阻塞套接字更好(这将消除检查 EAGAIN 的需要)?
  • @cHao:如果你在异步设计中使用阻塞套接字,你的程序通常可以工作,但当事情发生轻微错误时,就会出现莫名其妙的冻结。
  • @Zan:pollselect 的真正目的是告诉我们在没有阻塞的情况下我们可以做什么。如果它告诉我们有数据要读取,那么读取一些数据不应该阻塞。在单线程进程中,或者如果只有一个线程进行套接字 I/O,poll 应该始终正确。如果它在撒谎,那么操作系统就坏了。
  • @cHao:然后用阻塞套接字来实现你的程序。玩得开心,让它 100% 发挥作用。
  • @Zan:我有。一些。它确实有效,100%。这就是为什么我要询问使用非阻塞套接字的原因;我从来没有遇到过由不适当的阻止引起的问题。我想知道他们解决了哪些select/poll 和指定的 I/O 线程尚未解决的问题。
【解决方案2】:

i need to response more than one clients.

使用Threading

【讨论】:

  • 取决于软件需要处理的客户端数量。每个客户端一个线程可以变得非常大,非常快。
  • 另外,线程很难正确处理,也很难调试。与 select() 或 poll() 或类似的多路复用通常更简单。
【解决方案3】:

基本上,您希望您的主线程只执行接受部分,然后将其余部分处理到另一个执行线程(可以是线程或进程)。

每当您的主线程从“accept”返回时,将套接字描述符提供给另一个线程,然后再次调用 accept(这可以通过 fork、pthread_create 或通过维护线程池和使用同步来完成,例如条件变量, 表示新客户端已被接受)。

虽然主线程将处理可能传入的新客户端,但其他线程将处理接收/发送。

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 2020-09-18
    • 2011-04-28
    相关资源
    最近更新 更多