我正在开发一个视觉应用程序,它有两种模式:
1)参数设置
2)自动
当我的应用程序通过TCP / IP等待信号时,问题出现在2)中。程序冻结而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()
吗?
感谢。
致以最诚挚的问候,
Ť
答案 0 :(得分:2)
解决方案是仅在有传入连接请求时调用accept()。您可以通过在侦听套接字上进行轮询来执行此操作,您还可以在其中添加其他文件描述符,使用超时等。
你没有提到你的平台。在Linux上,请参阅epoll(),UNIX请参阅poll()/ select(),Windows我不知道。
答案 1 :(得分:1)
一种方法是在超时循环中运行select
。
将slisten
置于非阻止模式(这不是绝对必要的,但有时accept
阻止,即使select
另有说明),然后:
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
答案 2 :(得分:0)
一般方法是使用本地TCP连接,UI线程可以通过该连接中断select
调用。一般架构将使用:
select
和本地TCP连接上等待slisten
的专用线程只需声明select
应该读取slisten
和本地套接字。一旦准备就绪,它将立即返回,您将能够知道哪一个准备就绪。
答案 3 :(得分:0)
由于您尚未指定您的平台,并且网络(尤其是异步)是特定于平台的,因此我认为您需要跨平台解决方案。 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可以是仅限标头的lib,并且无需使用Boost:http://think-async.com/Asio/AsioAndBoostAsio。