C - 使用 select() 时如何限制服务器中的入站连接数 [英] C - How to limit the number of inbound connections in a server when using select()

查看:51
本文介绍了C - 使用 select() 时如何限制服务器中的入站连接数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm still new to C socket programming but I was able to create some simple client and server programs. I'm programming a server that listens for TCP connections, its duty is answering to clients' requests and then close the communication when the client sends a special sequence of bytes (or when it disconnects, of course).

我开始在无限循环中使用 accept() 函数对服务器进行编码:服务器等待客户端,accept() 是它,完成所有事情,close() 是套接字描述符并再次返回等待接受新客户端.

I started coding the server using the accept() function inside an endless loop: the server waits for a client, accept()'s it, does all the stuff, close()'s the socket descriptor at the end and goes back again waiting to accept a new client.

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

Since I want to serve one client at a time I called the listen function in this way: listen(mysocket, 1);

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

Everything worked pretty well, but then a new problem came out. The server part explained above runs in a separated thread (let's call it thread #2) and the main thread (thread #1) must be able to tell it to terminate. I created a global variable then, if this variable is set to 1 (by thread #1) thread #2 must terminate. The problem is that thread #2 gets stuck when the accept() function is called, thus it can't periodically check the global variable.

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

I clearly needed a timeout value for that function: "if there isn't a connection to accept, check the value of the global variable, continue waiting for new connection if set to 0 or terminate if set to 1".

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

I googled for a solution then and found that the select() function does the thing that I need. It's a little bit different though, I discovered for the first time the fd_set and all the FD_* macros. I modified the server part to make it work with the select() function and everything works really nice, but here comes the last problem, the one that I'm not able to solve. If call the listen function this way: listen(socket, 1); but the server still accepts and serves multiple connections at the same time. Does this depend because select() works with fd_set's? I'm using some examples I found on the web and, when a connection is accepted, it creates a new socket descriptor that goes in the set with all the others. I'd like to accept the connection of just one client, I wrote a simple code that recognizes if the connecting client should be served or not, but is there a way to disconnect it server side? I know that I have to use the close() function to close a socket descriptor, but when using select() I'm working with fd_set's and I don't really know what to do to close them. Or, is there a way to limit the number of socket descriptors in a set? I found the FD_SETSIZE macro, but I wasn't able to make it work and I'm not even sure if it fixes the problem.

感谢您的宝贵时间!

推荐答案

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

The listen() function has a backlog argument that determines how many incoming request may be pending before they may be turned away. This is worded carefully so that the OS implementation can support more than what you specify in the listen() call. You may not be able to control the exact number of backlogged connections.

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

If you must support only one client at a time, then accept a second connection but tell the new client that the connection is not available at this time, and then close the new connection. This also has the benefit that you have the opportunity to tell the client why the connection is not available.

这篇关于C - 使用 select() 时如何限制服务器中的入站连接数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆