TCP服务器在C中同时侦听多个客户端

TCP服务器在C中同时侦听多个客户端,c,tcp,C,Tcp,我已经为TCP服务器编写了C代码,以便一次侦听一个客户机。。但我很难弄清楚如何让服务器一次侦听多个客户端 有人知道一个好的教程或例子来解释这一点吗 谢谢 参见手册2选择 这应该是你想要的。小心,未经测试: listen_any(int n, int *s, void receiver(int *)) { FD_SET set; int x = -1; int i; for (i = 0; i < n; ++i) if (x < s[i]

我已经为TCP服务器编写了C代码,以便一次侦听一个客户机。。但我很难弄清楚如何让服务器一次侦听多个客户端

有人知道一个好的教程或例子来解释这一点吗

谢谢

参见手册2选择

这应该是你想要的。小心,未经测试:

listen_any(int n, int *s, void receiver(int *))
{
    FD_SET set;
    int x = -1;
    int i;
    for (i = 0; i < n; ++i)
        if (x < s[i]) x= s[i];
    while (1) {
        FD_ZERO(&set);
        for (i = 0; i < n; ++i)
            FD_SET(s[i], fd);
        select(x, &set, NULL, NULL, NULL);
        for (i = 0; i < n; ++i)
            if (FD_ISSET(s[i], fd)) {
                struct socakddr sa;
                int len = sizeof(sa);
                int sn = accept(s[i], &sa, &len);
                if (sn >= 0) {
                    if (!receiver(sn))
                       close(sn);
                }
            }
    }
}
见男子2选择

这应该是你想要的。小心,未经测试:

listen_any(int n, int *s, void receiver(int *))
{
    FD_SET set;
    int x = -1;
    int i;
    for (i = 0; i < n; ++i)
        if (x < s[i]) x= s[i];
    while (1) {
        FD_ZERO(&set);
        for (i = 0; i < n; ++i)
            FD_SET(s[i], fd);
        select(x, &set, NULL, NULL, NULL);
        for (i = 0; i < n; ++i)
            if (FD_ISSET(s[i], fd)) {
                struct socakddr sa;
                int len = sizeof(sa);
                int sn = accept(s[i], &sa, &len);
                if (sn >= 0) {
                    if (!receiver(sn))
                       close(sn);
                }
            }
    }
}

在使用上一个侦听器时只需创建另一个侦听器

在使用上一个侦听器时只需创建另一个侦听器

实现此目的的方法有很多,其中一些是:

使用select基本上等待一组文件描述符,直到其中一个已准备好读取或写入。 使用线程(如pthreads)将单个会话转移到一个进程内的单独线程。 使用fork复制处理会话的进程,以便fork进程处理该会话,而原始进程返回到等待更多连接。 在这些中,我更喜欢中间的那个。分叉一个进程有时是一个代价高昂的操作,因为如果任何一个进程试图更改数据,通常都必须复制数据

select选项意味着您的代码必须管理多个会话,有时会变得混乱


使用线程,您可以相对轻松地将会话彼此分离,而不会产生进程复制的成本。当然,如果你不小心,线程有它自己的陷阱,但是一旦你理解了潜在的问题区域,我认为它是一个更好的选择。

< P>有很多方法来实现这一点,其中一些是:

使用select基本上等待一组文件描述符,直到其中一个已准备好读取或写入。 使用线程(如pthreads)将单个会话转移到一个进程内的单独线程。 使用fork复制处理会话的进程,以便fork进程处理该会话,而原始进程返回到等待更多连接。 在这些中,我更喜欢中间的那个。分叉一个进程有时是一个代价高昂的操作,因为如果任何一个进程试图更改数据,通常都必须复制数据

select选项意味着您的代码必须管理多个会话,有时会变得混乱


使用线程,您可以相对轻松地将会话彼此分离,而不会产生进程复制的成本。当然,如果你不小心,线程有它自己的陷阱,但是一旦你了解潜在的问题区域,我认为这是一个更好的选择。它支持几种流行的高可扩展性服务器应用程序。

看看libevent。它支持几种流行的高可扩展性服务器应用程序。

您在哪个平台上?如果是Windows,则是一种流行的平台API。如果是Linux,从低级到高级的流行选择可能是Joshua、epoll、kqueue或libevent/libev提到的类似但略有不同的库,这些库是前面API上的抽象层


select非常便于移植,但在大多数情况下并不是最优的。自它创建以来,我们已经学到了很多东西。尽管如此,如果您不需要疯狂的性能,并且希望坚持使用相当标准的C编程,那么这将是一个不错的选择,并且有大量的文献提到它。一旦您的服务器使用select,将其更改为更高级的多路复用API应该不会太难。

您在哪个平台上?如果是Windows,则是一种流行的平台API。如果是Linux,从低级到高级的流行选择可能是Joshua、epoll、kqueue或libevent/libev提到的类似但略有不同的库,这些库是前面API上的抽象层

select非常便于移植,但在大多数情况下并不是最优的。自它创建以来,我们已经学到了很多东西。尽管如此,如果您不需要疯狂的性能,并且希望坚持使用相当标准的C编程,那么这将是一个不错的选择,并且有大量的文献提到它。一旦您的服务器使用select,将其更改为更高级的多路复用API应该不会太难。

这是一个非常酷的网络或消息传递库,它将“select”或传统套接字从代码中移除

结帐
这是一个非常酷的网络或消息传递库,它将“select”或传统套接字从代码中移除

不知道是否与此有关,但…可以使用以下变体:

listener.Start()
While True
    Dim user As New chatclient(listener.AcceptTcpClient)
End While

不知道是否与此有关,但…可以使用以下变体:

listener.Start()
While True
    Dim user As New chatclient(listener.AcceptTcpClient)
End While

你在使用什么平台?你在使用什么平台?