我的.NET客户端/服务器应用程序使用TcpClient
和SSLStream
与线路协议进行通信。基本上,他们交换一些信息,然后进入心跳循环,客户端定期向服务器发送消息并接收答案。
这种方法效果很好,并且可以持续数天,但有时连接会因为套接字错误代码10054或10060而中断,说主机没有响应。
为了进行测试,我摆脱了大多数代码并尝试使用非常少的组件。
在服务器上,我使用TcpListener
并在新任务中为新客户端运行此代码(请注意我已从示例中删除了日志记录代码):
Private Sub HandleClient(c As TcpClient)
c.NoDelay = True 'I tried with and without this algorithm
Dim stream = c.GetStream
Dim buffer(1024) As Byte
c.ReceiveTimeout = 60000
Do
Dim value As Integer = 0
Try
value = stream.Read(buffer, 0, buffer.Length)
Catch ex As Exception
End Try
For i = 0 To value - 1
buffer(i) = 0 'Just to get rid of residuals for error checking
Next
stream.Write({1, 45, 26}, 0, 3)
Loop
End Sub
大多数只是记录,我发送的值只是一些随机数。所以在这里我从NetworkStream
读取值并写回一些数字。注意:在实际应用中,我使用WriteLine
和ReadLine
。
客户端代码同样简短,它也是在一个新任务中启动的:
Private Sub Connect()
'Get the ip to connect to from the command line, or use localhost
Dim ip = If(My.Application.CommandLineArgs.Count > 0, My.Application.CommandLineArgs(0), "127.0.0.1")
log("Trying to parse " & ip)
Dim parsed As IPAddress = Nothing
If IPAddress.TryParse(ip, parsed) = False Then parsed = IPAddress.Parse("127.0.0.1")
Dim c As New TcpClient()
c.NoDelay = True
c.Connect(parsed, 16543)
Dim stream = c.GetStream
Dim buffer(1024) As Byte
Do
stream.Write({33, 75, 123, 3}, 0, 4)
Dim value As Integer
Try
value = stream.Read(buffer, 0, buffer.Length)
Catch ex As Exception
End Try
For i = 0 To value - 1
buffer(i) = 0 'Just to get rid of residuals for error checking
Next
'Write a message every 5 seconds
Threading.Thread.Sleep(5000)
Loop
End Sub
我在普通的客户端和服务器应用程序旁边运行它,它可以完美地工作,但在与我的正常客户端/服务器连接完全相同的时候断开连接。快速的结论是该设备上的互联网连接存在问题。
但是,我还调整了一个小的python脚本基本上做了一些事情,它连接并交换Hello World字符串:
服务器:
import socket
import time
from datetime import tzinfo, timedelta, datetime
TCP_IP = 'this server'
TCP_PORT = 7777
BUFFER_SIZE = 20
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn,addr = s.accept()
while 1:
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
conn.send("World!")
conn.close()
客户端:
import socket
import time
from datetime import tzinfo, timedelta, datetime
TCP_IP = 'my server'
TCP_PORT = 7777
BUFFER_SIZE = 1024
MESSAGE = "Hello"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while 1:
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
time.sleep(5)
s.close()
我也在同一台机器上运行它,它没有任何问题。它只是继续发送,所以我猜互联网连接没问题。
当服务器在vServer异地运行时,客户端位于NAT路由器后面。
所以,总结一下:
我真的不知道这个问题可能是什么原因。
我尝试过的事情是:
使用异步读/写操作而不是同步,启用/禁用Nagle算法(NoDelay
),发送原始字节而不是使用WriteLine
/ ReadLine
。
它可能取决于机器或连接,因为其他连接上的其他两个测试客户端在过去几天似乎运行稳定。但它似乎也依赖于实现,因为Python脚本永远有效。
对于文本/代码的墙,我感到很抱歉,我对我出错的地方有任何想法。