我的tcp通信模型是这样的:
服务端有一个线程等待客户端连接(accept),当有客户端连接上(connect)时,服务端开启一个接收线程(即每客户一个接收线程),用于接收(receive)客户端发送的数据。
现在的问题是:
当只有一个客户端连接上时,程序是没有问题的,假如在服务其跟连接上的客户端交互时,又有第二个客户端连接上,那么一段时间后,服务端的接收线程(用于接收第一个客户端请求的线程)中的receive函数就会出错,错误码是10054(远程主机强迫关闭了一个现有的连接。)
希望高人指点指点,或者有谁曾经碰到类似的问题,希望能告诉我是怎么解决的.
注意:我的客户端是嵌入式开发的,是采用北京中新创科技有限公司的DNS-1-485产品
我的代码是:
- VB.NET code
private DNSAcceptSocket as system.net.socket Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim DNSthread As New Thread(New ThreadStart(AddressOf mainDNS)) DNSthread.Start() '起动监听DNS线程 end sub Private Sub mainDNS() Dim HostIP As IPAddress Dim Server As IPEndPoint Try MyHostIP = System.Net.IPAddress.Parse(System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName).AddressList(0).ToString()) Server = New System.Net.IPEndPoint(MyHostIP, Int32.Parse("5555")) DNSSocket = New System.Net.Sockets.Socket( _ System.Net.Sockets.AddressFamily.InterNetwork, _ System.Net.Sockets.SocketType.Stream, _ System.Net.Sockets.ProtocolType.Tcp) DNSSocket.Bind(Server) DNSSocket.Listen(50) Try If DNSSocket Is Nothing Then Return Do While True If ListenLoop = False Then Exit Do End If DNSAcceptSocket = DNSSocket.Accept Dim myThread As New Thread(New ThreadStart(AddressOf DNSAcceptConnection)) myThread.IsBackground = True '将线程在后台运行 myThread.Start() '每有连接请求并接收后就起动一个分析数据线程 Loop Catch ex As SocketException ' MessageBox.Show(ex.Message) End Try Catch ex As SocketException MessageBox.Show("请重新起动软件") ExitApp() ' MessageBox.Show("服务器监听DNS" & ex.Message) End Try End Sub Private Sub DNSAcceptConnection() Label.CheckForIllegalCrossThreadCalls = False RichTextBox.CheckForIllegalCrossThreadCalls = False Dim lngAcceptData As Long '记录传过来的字节数 Dim EndPoint As String '记录传过来工程的IP与端口号 Dim AcceptArray() As String Dim AcceptGCdata As String = Nothing '记录从客户端传过来的数据 Dim sql As String Dim FireTypeDSet As New DataSet Dim NowDate As String '记录现在的时间 Dim Gongchengname As String Dim d1(1) As Byte Dim AcceptSocket As Socket = DNSAcceptSocket '实例化接收数据的Socket套接口 EndPoint = AcceptSocket.RemoteEndPoint.ToString '记录连接服务器的客户的IP地址与端口 Dim IP As String = EndPoint.Substring(0, EndPoint.IndexOf(":")) '取出传过来的工程IP地址 Try If DNSSocket Is Nothing Or AcceptSocket Is Nothing Then Return Dim bteAcceptData(120) As Byte If AcceptSocket.Connected Then '判断是否处于连接状态 lngAcceptData = AcceptSocket.Receive(bteAcceptData) '接收客户端传过来的数据 d1(0) = &HFD : d1(1) = &HFD '发送收到确认指令 AcceptSocket.Send(d1) ' 将收到的信息转换为十六进制字符串() DoLoopCount = 0 For i As Integer = 0 To lngAcceptData - 1 DoLoopCount = DoLoopCount + 1 : If DoLoopCount > 2000 Then Exit For If bteAcceptData(i) > 15 Then AcceptGCdata = AcceptGCdata & Hex(bteAcceptData(i)) Else AcceptGCdata = AcceptGCdata & "0" & Hex(bteAcceptData(i)) End If Next i If RichTextBox1.Text.Length > 1000 Then RichTextBox1.Text = Nothing End If Gongchengname = SelectGongChengName(IP) '取得发过数据的县局名称 RichTextBox1.Text &= Gongchengname & ":" & AcceptGCdata & "(" & Date.Now & ")" & vbCrLf Catch ex As SocketException MessageBox.Show(ex.Message) End Try End Sub