从分离的线程中止套接字连接
Socket connect abort from a detached thread
我正在构建一个套接字客户端,在那里我需要实现连接、读取、写入的超时,以及协议本身的超时(缺少答案等)。
我正在考虑在分离的线程中使用一个简单的计时器,它将在每个事务上启动,然后在事务完成时取消。这种相同的方法将用于使用不同超时的协议控制。
测试是我做了以下简单的代码:
#include <string>
#include <sstream>
#include <map>
#include <iostream>
#include <cstring>
#include <thread>
#ifdef _WIN32
#include <io.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
bool timerOn = false;
int currentSocket = 0;
void Timer(int seconds)
{
int tick = seconds;
while (tick > 0)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
tick--;
}
if (timerOn)
close(currentSocket);
}
void StartTimer(int seconds)
{
timerOn = true;
std::thread t(&Timer, seconds);
t.detach();
}
void StopTimer()
{
timerOn = false;
}
void Connect(std::string address, int port)
{
struct addrinfo hints;
struct addrinfo *result = NULL;
struct addrinfo *rp = NULL;
int sfd, s;
std::memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPV4 or IPV6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
std::string portStr;
portStr = std::to_string(port);
s = getaddrinfo(address.c_str(), portStr.c_str(), &hints, &result);
if (s != 0)
{
std::stringstream ss;
ss << "Cannot resolve hostname " << address << gai_strerror(s);
throw std::runtime_error(ss.str());
}
for (rp = result; rp != NULL; rp = rp->ai_next)
{
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue;
StartTimer(10);
int sts = connect(sfd, rp->ai_addr, rp->ai_addrlen);
StopTimer();
if (sts == 0)
break;
close(sfd);
}
freeaddrinfo(result); /* Object no longer needed */
if (rp == NULL)
{
std::stringstream ss;
ss << "Cannot find server address at " << address << " port " << port;
throw std::runtime_error(ss.str());
}
currentSocket = sfd;
}
int main()
{
try
{
Connect("192.168.0.187", 9090);
std::cout << "Connected to server. Congrats!!!" << std::endl;
}
catch (std::exception& ex)
{
std::cout << "Error connecting to server. Aborting." << std::endl;
std::cout << ex.what() << std::endl;
}
}
关闭计时器上的套接字并不是取消"连接"操作,而是迫使它因错误而中止。我也尝试过shutdown(sfd, SHUT_RDWR);
,但没有成功。。。
我的方法无效吗?为什么它不起作用?
如何强制connect
在分离线程出现错误时中止?
关闭计时器上的套接字并不是取消"连接"操作,而是迫使它因错误而中止。
哇!你绝对不能那样做。当您关闭套接字时,无法知道线程实际上在connect
中被阻塞(而不是即将调用connect
)。在一个线程中释放资源,而另一个线程正在或可能正在使用它,这将导致灾难。
想象一下这种情况:
-
线程即将调用
connect
,因此它会安排一个超时。 -
超时到期,套接字关闭。
-
某个库中的线程出于自身原因创建了一个新的套接字来使用,从而获得了相同的套接字描述符。
-
即将调用
connect
的线程最终得到调度并调用connect
——连接库的套接字!灾难
你有两个选择:
-
使用非阻塞
connect
操作。 -
使用类似于信号的东西来中断调用
connect
的线程。
但我不得不怀疑你为什么这么麻烦。为什么需要中止连接?如果您需要做其他事情,如果在超时之前连接没有成功,只需继续执行即可。
相关文章:
- 当套接字连接断开时检测C/C++Unix
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- 如何在 2 台主机之间保持 UDP 套接字连接打开
- Opencv 不适用于套接字连接
- C++通过套接字连接发送矢量
- mbed 套接字连接需要很长时间
- 重用多个请求的相同套接字连接
- C++ Linux 上的套接字连接
- 套接字连接在主功能内部但不在功能内部
- 套接字连接上的缓冲区溢出
- 套接字连接()被误认为是QT connect()
- 返回打开的插座连接/留下套接字连接打开C
- 当试图连接到无法到达的计算机时,C 套接字连接被卡住
- C# 客户端到C++服务器 Tcp 套接字连接错误
- C [UDP]如何跟踪服务器上的所有连接(客户端)套接字连接
- 使用C 安全套接字连接
- 在C 中每分钟之后,如何检查套接字连接
- 正在创建多个TCP套接字连接
- 为什么我不能通过套接字连接android和PC
- 从分离的线程中止套接字连接