我正在编写一个客户端 - 服务器程序,其中客户端是C ++ / winapi,服务器是C#/ .net。
客户端有一个循环,它从服务器读取(可能会阻塞调用线程[表示t1],这对我来说没问题)。它还有另一个线程[表示t2],等待具有超时的Event对象。
如果达到超时(并且尚未单个事件)t2线程将在同一个套接字上写(exacly on byte)。
我遇到的问题是,似乎写入不会返回,直到t1上的读取返回(在某些合法的scnerions中它永远不会发生),就像套接字不是全双工一样。
P.S:socket是一个AF_INET / SOCK_STREAM,我正在使用Readfile和WriteFile来实现套接字IO。
感谢。
答案 0 :(得分:0)
套接字不是read()和write(),或者send()和recv()都不是这样的。你必须有自己的同步。
答案 1 :(得分:0)
我用WinSock编程了十多年,我可以向你保证套接字总是全双工的。
WriteFile()
(或send()
或WSASend()
)阻止调用线程任何时间的唯一方法是套接字是以阻塞模式运行还是其数据的出站队列等待传输已完全填满(队列的大小由SO_SNDBUF
套接字选项控制)。这表示另一方(您的C#服务器)没有从其套接字端点读取入站数据并及时确认收到的数据,因此您的套接字端点可以从其出站队列中删除该数据,以便可以接受新数据进行传输。
如果您不希望拨打WriteFile()
来阻止,可以:
启用SO_SNDTIMEO
套接字选项以指定阻止写入的超时。
使用select()
,WSAAsyncSelect()
或WSAAsyncEvent()
来检测套接字何时实际可写(即,何时可以无阻塞地接受数据),然后再将新内容写入插座。
切换到非阻塞I / O,异步重叠I / O或I / O完成端口。