如何在 TCP/IP 服务器中中断 accept()?
How to interrupt accept() in a TCP/IP server?
我正在开发一个视觉应用程序,它有两种模式: 1) 参数设置 2) 自动 问题出在 2) 中,当我的应用程序通过 TCP/IP 等待信号时。调用 -methode 时程序冻结accept()
。我想在 GUI 上提供更改模式的可能性。因此,如果模式发生变化,则由另一个信号(message_queue)提供。所以我想中断接受状态。 是否有一个简单的可能性来中断接受?
std::cout << "TCPIP " << std::endl;
client = accept(slisten, (struct sockaddr*)&clientinfo, &clientinfolen);
if (client != SOCKET_ERROR)
cout << "client accepted: " << inet_ntoa(clientinfo.sin_addr) << ":"
<< ntohs(clientinfo.sin_port) << endl;
//receive the message from client
//recv returns the number of bytes received!!
//buf contains the data received
int rec = recv(client, buf, sizeof(buf), 0);
cout << "Message: " << rec << " bytes and the message " << buf << endl;
我读过select()
但我不知道如何使用它。任何人都可以给我一个提示,例如如何在我的代码中实现例如select()
?
谢谢。
此致敬意
T
解决方案是仅在有传入连接请求时才调用accept()。您可以通过在侦听套接字上轮询来做到这一点,您还可以在其中添加其他文件描述符、使用超时等。
你没有提到你的平台。在Linux上,参见epoll(),UNIX参见poll()/select(),Windows I not know。
一般方法是使用本地 TCP 连接,UI 线程可以通过该连接中断select
调用。一般体系结构将使用:
- 在
slisten
和本地 TCP 连接上等待select
的专用线程 - UI 线程和等待线程之间的 TCP 连接(Unix 或类 Unix 系统上的 Unix 域套接字,或 Windows 上的 127.0.0.1)
- 根据需要在两个线程之间进行各种同步/消息
只需声明select
应该读取slisten
和本地套接字。一旦准备好了,它就会返回,您将能够知道哪一个准备好了。
由于您尚未指定平台,并且网络(尤其是异步)是特定于平台的,因此我认为您需要一个跨平台的解决方案。Boost.Asio
非常适合这里:http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/reference/basic_socket_acceptor/async_accept/overload1.html
链接中的示例:
void accept_handler(const boost::system::error_code& error)
{
if (!error)
{
// Accept succeeded.
}
}
...
boost::asio::ip::tcp::acceptor acceptor(io_service);
...
boost::asio::ip::tcp::socket socket(io_service);
acceptor.async_accept(socket, accept_handler);
如果Boost
是一个问题,Asio 可以是一个仅标头的库,并且在没有 Boost: http://think-async.com/Asio/AsioAndBoostAsio 的情况下使用。
一种方法是在具有超时的循环中运行select
。
将slisten
置于非阻塞模式(这不是绝对必要的,但有时即使select
另有说明,也会accept
块),然后:
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(slisten, &read_fds);
struct timeval timeout;
timeout.tv_sec = 1; // 1s timeout
timeout.tv_usec = 0;
int select_status;
while (true) {
select_status = select(slisten+1, &read_fds, NULL, NULL, &timeout);
if (select_status == -1) {
// ERROR: do something
} else if (select_status > 0) {
break; // we have data, we can accept now
}
// otherwise (i.e. select_status==0) timeout, continue
}
client = accept(slisten, ...);
这将允许您每秒捕获一次信号。更多信息在这里:
http://man7.org/linux/man-pages/man2/select.2.html
和Windows版本(几乎相同):
https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms740141(v=vs.85).aspx
- 类成员和中断
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 我的代码运行良好,但在游戏循环中中断
- 使用带有MCP23017的 pigpio 进行中断读取
- 为什么我在 AVR 中的中断无法正常工作?
- 使用 UDP 中断 while()-循环
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何在 CompleteAsyncIO 中访问 IOMemoryBufferDescriptor,该描述符通过中断 EP
- 如何为伺服电机创建中断或返回值?
- 开关:无外壳中断
- 如何使用中断停止循环?
- 为什么当我输入一个被接受的数字时,我的 do-while 循环没有中断?
- 在 Ubuntu 中编译 SuiteSparse,在安装 CHOLMOD 时中断
- 在PROGMEM中添加更多数据会中断Arduino Mega 2560上的SPI传输
- 附加到 gdb 会中断并且不会继续该过程
- 使用 shared_ptr 在中断时结束多线程循环
- 如何在 TCP/IP 服务器中中断 accept()?
- 如何中断libfcgi中的Accept方法
- 正在中断accept()
- 用MFC中的异步过程调用中断一个accept winsock调用