2

我还是 C 套接字编程的新手,但我能够创建一些简单的客户端和服务器程序。我正在编写一个侦听 TCP 连接的服务器,它的职责是响应客户端的请求,然后在客户端发送特殊的字节序列时(或者当它断开连接时)关闭通信。

我开始使用无限循环中的函数对服务器进行编码accept():服务器等待客户端,accept() 完成所有工作,close() 是最后的套接字描述符,然后再次返回等待接受一个新客户。

因为我想一次服务一个客户,所以我用这种方式调用了监听函数:listen(mysocket, 1);

一切都很顺利,但随后又出现了一个新问题。上面解释的服务器部分在一个单独的线程中运行(我们称之为线程#2),主线程(线程#1)必须能够告诉它终止。然后我创建了一个全局变量,如果这个变量设置为 1(由线程 #1),线程 #2 必须终止。问题是线程#2 在调用函数时卡住了accept(),因此它不能定期检查全局变量。

我显然需要该函数的超时值:“如果没有要接受的连接,请检查全局变量的值,如果设置为 0,则继续等待新连接,如果设置为 1,则终止”。

然后我搜索了一个解决方案,发现该select()功能可以满足我的需求。不过有点不同,我第一次发现了fd_set所有的 FD_* 宏。我修改了服务器部分以使其与该select()功能一起工作,并且一切都非常好,但这是最后一个问题,我无法解决的问题。如果以这种方式调用监听函数:listen(socket, 1);但服务器仍然同时接受并服务多个连接。这是否取决于因为select()与 fd_set 一起使用?我正在使用我在网上找到的一些示例,当连接被接受时,它会创建一个新的套接字描述符,该描述符与所有其他套接字描述符一起放入集合中。我只想接受一个客户端的连接,我编写了一个简单的代码来识别是否应该为连接的客户端提供服务,但是有没有办法断开它的服务器端?我知道我必须使用该close()函数来关闭套接字描述符,但是在使用时select()我正在使用 fd_set,我真的不知道该怎么做才能关闭它们。或者,有没有办法限制一组套接字描述符的数量?我找到了 FD_SETSIZE 宏,但我无法让它工作,我什至不确定它是否能解决问题。

感谢您的时间!

4

3 回答 3

5

listen()函数有一个backlog参数,用于确定有多少传入请求在被拒绝之前可能处于未决状态。这措辞谨慎,以便操作系统实现可以支持比您在调用中指定的更多内容。listen()您可能无法控制积压连接的确切数量。

如果您必须一次只支持一个客户端,则接受第二个连接但告诉新客户端该连接此时不可用,然后关闭新连接。这还有一个好处是您有机会告诉客户端连接不可用的原因。

于 2012-07-08T22:00:23.407 回答
0

您也可以将 listen() 套接字放入 fd_set。(如果你已经这样做了,我不明白你的问题)如果选择表明监听套接字是可读的,你可以在监听套接字上调用接受。接受正好返回一个 fd。您也可以将返回的 fd 放入 fd_set。线程或多或少与此正交。(系统调用是原子的),但你当然可以把事情搞砸。

listen 的 backlog 参数或多或少无关;它只是指定系统应该同时维护多少个胚胎套接字(连接建立使用资源,甚至在套接字变得可用之前,如侦听返回新的 fd 所示)一旦完成三次握手,accept 将返回 fd,并且胚胎连接作为新的套接字 fd 诞生

getdtablesize() 宏是旧时代的遗留物。在现代实现中,它基于 getrlimit()。

FD_SETSIZE 的根本问题是 fd_set 必须是一个左值,这样才能对其进行分配。所以它必须是固定大小的。(它可能是结构内的一个数组)为了避免固定大小的结构,您可以使用 poll() 而不是 select() (或使用多个较小的 fd_sets ;-)

于 2012-07-08T22:09:18.440 回答
-1

如果您使用的是 windows API,您可以尝试使用关键部分。

于 2012-07-08T21:59:20.117 回答