【发布时间】:2015-04-13 05:40:57
【问题描述】:
int tcp_sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in remoteaddr;
struct sockaddr_in localAddr;
short local_port = 22222;
short remote_port = 33333;
// local addr
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(local_port);
localAddr.sin_addr.s_addr = 0xC0A80AA5; // we don't give a shit
int addrLen = sizeof(struct sockaddr_in);
//Now bind TCP to local addr
int result = bind(tcp_sock,(struct sockaddr*)&localAddr,addrLen);
if (result < 0)
{
perror("\nbind failed");
close(tcp_sock);
return -1;
}
result = connect(tcp_sock, (struct sockaddr*)&remoteaddr, sizeof(struct sockaddr_in));
printf("\nConnect returned %d, error no: %d", result, errno);
这里connect() 调用很长时间后失败。有什么方法可以让connect 函数在我选择的一段时间后返回?我尝试从另一个线程调用close(),但这并没有改变任何东西。
【问题讨论】:
-
你不能在另一个线程中调用
close。你甚至不能尝试。想一想——如何确保close出现在connect开始阻塞之后而不是在它之前? -
@DavidSchwartz:这有关系吗?
close事先应该会在connect尝试上导致错误代码 (EBADF?)。如果connect()已经在飞行中,我会更担心会发生什么...... -
FWIW /-如果套接字在任何线程的
connect之前是closed,我在Linux 上的测试会产生“错误的文件描述符”,但如果connect已经在运行,则不会“超时”/返回。 -
@TonyD 这非常重要。想象一下,如果在您调用
close之后,但在connect执行之前,在另一个线程中运行的系统库调用socket,并且您最终连接了一个不属于您的套接字。这可能会导致敏感信息被发送到不受信任的端点。您的测试就像过马路,它恰好是空的,但不看两边,并推断出不看两边的情况下过马路是安全的。 (是的,这确实发生了。) -
@DavidSchwartz:在后台线程可能正在创建套接字的情况下,这很重要;分开-在您的第一条评论中可能有一个无意的推论,如果
close可以保证在connect阻塞之后发生,那么它可能会起到超时的作用;正如我的测试所示,这具有误导性。
标签: c++ sockets tcp network-programming blocking