2016-12-13 182 views
-1

它不是真的重复。当使用非阻塞套接字时,你必须使用select方法来检查连接是否被创建,在select方法中你可以设置一个超时值来终止。比方说,如果我想在预设的超时值之前中断选择方法,那又是同样的问题。在我的情况下,选择超时时间最长可达5分钟,以防打印机忙于做某些事情而没有时间回复。break tcpip连接方法

从另一个线程关闭套接字取消连接,或选择,似乎是我的问题的最佳解决方案。

我有程序连接到远程TCPIP端口,它是一台打印机。

SOCKET socket = socket(AF_INET, SOCK_STREAM, 0); 
struct sockaddr_in SockAddr; 
//... initialized host and port and so on 
int iret = connect(socket, &SockAddr, sizeof(SockAddr)); 
if (iret != 0) 
{ 
    // get error code... 
} 

只要打印机打开,它工作正常。如果打印机关闭,连接将失败,并且“主机不可达”,这也很好。

如果打印机处于关闭状态,连接方法将被阻止约20到21秒,然后返回失败。这20秒应该从一些系统配置中计算出来,这很可能但很难改变。在其他系统上,这可能会更长。

我的问题是,是否有可能从连接方法,通过从另一个线程的另一个调用中断?如果我发现打印机未打开,我想取消连接,不要停止应用程序,而是继续执行一些日志记录作业。

如果我在进程中附加调试,暂停然后继续,它似乎会提前中断。

我不能在这里使用非块套接字,因为它是一个非常大的项目,其他一切都是由其他人设计的块套接字。我不允许做大的改变。

+0

什么是“tcpip端口”?有TCP和IP。两者都是不同的网络层。 – Olaf

+0

@Olaf过于迂腐 - 将两者结合在一起称为TCPIP – Alnitak

+1

@Alnitak:“数以百万计的苍蝇不会错:吃sh **”:-)认真地说:仅仅因为使用错了并不意味着它应该是。混淆网络层是导致错误观念和问题的常见原因。 (它会过于迂腐,但要问什么“tcpip”,因为它通常被称为“TCP/IP”)。 – Olaf

回答

1

解除阻塞连接的最简单方法是关闭套接字。不幸的是,在等待连接时,你的thead被挂起,所以你将不得不关闭另一个线程的套接字。

替代解决方案将使用异步io Windows与OVERLAPPED io做到这一点。在Linux上,可以将套接字设置为非阻塞。这将导致connect在连接发生在后台时立即返回。然后可以使用select或poll来等待套接字准备就绪。如果你添加标准输入到选择,按键会中断选择ABD可以根据需要进行处理。

+0

我正在尝试此操作,但它需要一段时间。套接字被打开并存储在一个结构中,我必须让主线程访问套接字。 –

+0

最简单的方法是最好的。我只是从主线程调用closesocket,然后从阻塞的连接方法中断开。 17:00:08.371连接到172.20.17.26:5001 17:00:08.549立即取消 17:00 00:08.549连接失败10038 –