TCP服务器在C中同时侦听多个客户端
我已经为TCP服务器编写了C代码,以便一次侦听一个客户机。。但我很难弄清楚如何让服务器一次侦听多个客户端 有人知道一个好的教程或例子来解释这一点吗 谢谢 参见手册2选择 这应该是你想要的。小心,未经测试: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]
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
你在使用什么平台?你在使用什么平台?