socket通信问题

hnwl0507 2008-11-11 11:04:53
最近在搞一个网络通信的C/S模式下的软件,服务器与客户端的基本通信已完成了,可是出现了一个问题,就是当在客户端与服务器连接成功并能发收数据后,在客户端关闭连接后,服务器会产生错误:"远程主机强迫关闭了一个现有的连接。" 不知道这是怎么回事,我采用是多线程的模式
服务器的主要代码为:

Public MyHostIP As System.Net.IPAddress
Public MyServer As System.Net.IPEndPoint
Public MySocket As System.Net.Sockets.Socket
Public MyChattingState As Boolean
Public MyAcceptSocket As System.Net.Sockets.Socket
Dim MyThread As System.Threading.Thread
Dim thread As System.Threading.Thread
Public allDone As Threading.ManualResetEvent = New Threading.ManualResetEvent(False)
'创建聊天线程
Public Sub MyChatProcess()
Dim MyReceivedByte(7), MySendByte(4) As Byte
Dim MyReceivedString, MySendString As String
Dim socket As System.Net.Sockets.Socket = MyAcceptSocket
If (socket.Connected) Then
txt()
While (MyChattingState)
socket.Receive(MyReceivedByte, MyReceivedByte.Length, _
System.Net.Sockets.SocketFlags.None) '此处发生错误
MyReceivedString = _
System.Text.Encoding.BigEndianUnicode.GetString(MyReceivedByte)
list(MyReceivedString)

MySendString = "已收到"
MySendByte = System.Text.Encoding.BigEndianUnicode.GetBytes( _
MySendString.ToCharArray())
socket.Send(MySendByte, MySendByte.Length, _
System.Net.Sockets.SocketFlags.None)
MyReceivedString = Nothing
MySendString = Nothing
Array.Clear(MyReceivedByte, 0, MyReceivedByte.Length)
Array.Clear(MySendByte, 0, MySendByte.Length)
End While
End If
socket.Close()
End Sub
'创建聊天室
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Dim MyDelegate As New System.Threading.ThreadStart( _
AddressOf main)
thread = New System.Threading.Thread(MyDelegate)
thread.Start()
End Sub
Public Sub main()
Try
MyHostIP = System.Net.IPAddress.Parse(Me.textBox1.Text)
MyServer = New System.Net.IPEndPoint(MyHostIP, Int32.Parse("8888"))
MySocket = New System.Net.Sockets.Socket( _
System.Net.Sockets.AddressFamily.InterNetwork, _
System.Net.Sockets.SocketType.Stream, _
System.Net.Sockets.ProtocolType.Tcp)
MySocket.Bind(MyServer)
MySocket.Listen(50)
While (True)
MyAcceptSocket = MySocket.Accept
If MyAcceptSocket.Connected Then
Dim MyDelegate As New System.Threading.ThreadStart( _
AddressOf MyChatProcess)
MyThread = New System.Threading.Thread(MyDelegate)
MyThread.Start()
End If
End While
Catch ex As Exception
' Me.label5.Text = ex.Message
End Try
End Sub



在要关闭时是首先关闭客户端的Socket的
请高手们指教下
...全文
115 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hnwl0507 2008-11-17
  • 打赏
  • 举报
回复
uP
0暖沙0 2008-11-11
  • 打赏
  • 举报
回复
socket.Receive(MyReceivedByte, MyReceivedByte.Length, _
System.Net.Sockets.SocketFlags.None) '此处发生错误
在这句之前要加入判断
If socket.Available > 0 Then
获取已从网络接收且可供读取的数据量,如果不为零再进入读取,否则客户端关闭后你再读取就会出错
0暖沙0 2008-11-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 heng_s 的回复:]
服务器端接收客户端数据并进行处理和返回后,应该主动关闭Socket连接,而不是由客户端来主动关闭连接。
[/Quote]
判断通讯结束是一个方面,但不能避免客户端异常退出的情况,用socket.Available判断是否有数据是必须的
0暖沙0 2008-11-11
  • 打赏
  • 举报
回复
system.net.sockets.socket.select()可以用来确定一个或多个Socket实例的状态。通过调用Select,可以检查是否具有可读性。
(MSDN):“如果当前处于侦听状态,则可读意味着可成功地对 Accept 进行调用而没有阻止。如果当前已接受连接,则可读意味着有可读取的数据。这些情况下,所有的接收操作均可成功进行而没有阻止。可读性也可指示远程 Socket 是否已经关闭连接;如果连接已关闭,则对 Receive 的调用将立即返回,并返回零字节。”
你可以看下MSDN上的这个例子:使用Select来确定哪一个侦听套接字有连接请求。

Dim ipHostEntry As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = ipHostEntry.AddressList(0)

Dim socket0 As Socket = Nothing
Dim socket1 As Socket = Nothing
Dim socket2 As Socket = Nothing
Dim socket3 As Socket = Nothing
Dim socket4 As Socket = Nothing
Dim socket5 As Socket = Nothing

Dim listenList As New ArrayList()
listenList.Add(socket0)
listenList.Add(socket1)
listenList.Add(socket2)

Dim acceptList As New ArrayList()
acceptList.Add(socket3)
acceptList.Add(socket4)
acceptList.Add(socket5)

Dim i As Integer
For i = 0 To 2
listenList(i) = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
CType(listenList(i), Socket).Bind(New IPEndPoint(ipAddress, 11000 + i))
CType(listenList(i), Socket).Listen(10)
Next i

'Only the sockets that contain a connection request
'will remain in listenList after Select returns.
Socket.Select(listenList, Nothing, Nothing, 1000)

For i = 0 To listenList.Count - 1
acceptList(i) = CType(listenList(i), Socket).Accept()
Next i
oo渣渣oo 2008-11-11
  • 打赏
  • 举报
回复
服务器端接收客户端数据并进行处理和返回后,应该主动关闭Socket连接,而不是由客户端来主动关闭连接。
VirtualDesktop 2008-11-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hnwl0507 的回复:]
楼上的方法可行
但想问问system.net.sockets.socket.select()这个方法是做什么用的,如何用?
[/Quote]

select模型,建议你上网找找IO模型的相关资料
全速前行 2008-11-11
  • 打赏
  • 举报
回复
up
hnwl0507 2008-11-11
  • 打赏
  • 举报
回复
楼上的方法可行
但想问问system.net.sockets.socket.select()这个方法是做什么用的,如何用?

16,555

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧