首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VB Dotnet >

TCP多线程Socket错误有关问题

2012-02-12 
TCP多线程Socket异常问题我的tcp通信模型是这样的:服务端有一个线程等待客户端连接(accept),当有客户端连

TCP多线程Socket异常问题
我的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 




大家帮忙指点下,看看是不代码有问题


[解决办法]
估计是线程的问题,当有第二个客户端连接上时第一个客户端连接被断开了,所以才会提示远程主机强迫关闭了一个现有的连接。
先用你的代码测试下~
[解决办法]
MSDN里的范例可以参考一下,用的是BeginReceive和BeginSend[不用管线程问题]
[解决办法]
你把DNSAcceptSocket定义成一个公用变量,DNSAcceptSocket接受连接后就一直在处理对它本身进行处理,请问:
一个Socket连接如何同时处理两个不同的请求?

肯定会出问题的啊!

Dim myThread As New Thread(New ThreadStart(AddressOf DNSAcceptConnection))
这一句实际上是传的地址给新的线程,而不是另外新建了一个实例去处理!!!

你要这样改:
VB.NET code
'private DNSAcceptSocket as system.net.socket  这一句必须去掉!'中间接受连接的部分这样写   Do While True      If ListenLoop = False Then         Exit Do      End If      Dim AcptSocket As Socket = DNSSocket.Accept      Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf DNSAcceptConnection), AcptSocket)   Loop'下面的处理函数定义Private Sub DNSAcceptConnection(objSocket As Object)   Dim AcptSocket As Socket = CType(objSocket, Socket)   ......End Sub
[解决办法]
DNSAcceptSocket = DNSSocket.Accept
Dim myThread As New Thread(New ThreadStart(AddressOf DNSAcceptConnection))
myThread.IsBackground = True '将线程在后台运行
myThread.Start() '每有连接请求并接收后就起动一个分析数据线程

不要将THREAD使用到的任何变量定义为局部全局。尽量使用参数的方式来定义!
多THREAD模式下,最怕变量共享。
[解决办法]
好贴
[解决办法]
好东西,我得Copy下来。。。。。。。。。。

























电击小子小游戏
雷欧奥特曼
7k7k.com格斗小游戏
4399.com冒险小游戏
[解决办法]
好贴!学习了!
[解决办法]
把那部分另写成一个类应该就可以了

热点排行