我需要与一个旧的Java TCP服务器通信。它的工作方式是,我需要通过发送请求来建立连接,在请求之后,我订阅了事件,服务器通过连接向我发送数据,因此我需要始终侦听数据。这就是我所拥有的,它工作了一段时间,但过了一段时间它就停止接收了。
string logon = GetLogon();
client = new TcpClient(SERVER_IP, PORT_NO);
NetworkStream nwStream = client.GetStream();
byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(logon);
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
while (client.Connected)
{
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
var message = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
this.ProcessMessage(message);
}我在一个单独的函数中每分钟轮询服务器一次,以检查连接是否打开,即使我没有获得任何数据。
bool poll = client.Client.Poll(1000, SelectMode.SelectRead);
bool data = (client.Client.Available == 0);这是有效的,但大约20到60分钟后,我停止从服务器接收。谢谢你的帮助。
发布于 2020-09-21 23:19:59
似乎我的轮询机制没有使连接保持活动状态。
首先,我在套接字上尝试了这个设置。
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);在那之后,我的轮询机制开始检测到连接在一段时间后断开,但这只能使连接保持活动状态2小时。
然后,我偶然发现了这篇文章,它似乎起到了作用。https://darchuk.net/2019/01/04/c-setting-socket-keep-alive/
发布于 2020-09-16 19:05:01
尝试用Try catch包围你的代码,这样你就可以看到是否有任何异常。另外,不要使用client.connected,因为它只在您第一次连接时更改他的状态,而不是在客户端断开连接时更改,因此您的循环条件将始终为真。
尝试这样做(只需将读取代码放入循环中):
// Incoming message may be larger than the buffer size.
do{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while(myNetworkStream.DataAvailable);发布于 2020-09-16 20:12:20
我看到了,但连接并不意味着你总是有数据要读。您没有任何条件来验证是否有可用的数据可供读取。至少在循环中添加一条if语句来检查数据的可用性。
https://stackoverflow.com/questions/63917485
复制相似问题