套接字侦听和连接

Posted

技术标签:

【中文标题】套接字侦听和连接【英文标题】:Socket Listen and Connect 【发布时间】:2016-11-19 00:02:31 【问题描述】:

我设置了一个 System.Net.Sockets.Socket。我启动套接字侦听传入连接以接受套接字请求。这个相同的套接字应该能够停止监听和写入并连接到其他套接字。将套接字设置为 Listen 后,我无法让它发送连接命令。我得到这个例外:

“System.InvalidOperationException”类型的未处理异常发生在 系统.dll 附加信息:调用 Listen 方法后,您可能无法执行此操作。

如何更改其状态并允许其更改连接并返回监听?我正在使用 TCP 本地主机

Public Class SocketHandler

Private Socke As Sockets
Private connectThread As Thread
Private listenThread As Thread 
Private listening As Boolean = False

Public Sub New()
       listenThread = New Thread(Address of Listen)
       listenThread.IsBackground = True
       listenThread.Start()
End New

Private Sub Listen()
       Socke.Bind(New IPEndPoint(IPAddress.Any, Socke.Port))
       Socke.Listen(5)
       While Listening
             Dim Sock As Sockets = DirectCast(Socke.Accept(), Sockets)
             If Not Socke.Clients.Contains(Sock) Then
                  Socke.Clients.Add(Sock)
             End If
       End While
End Sub

Private Connect(ByVal sock As Sockets)
      connectThread = New Thread(Sub() Connecting(sock))
      connectThread.IsBackground = True
      connectThread.Start()
End If

Private Sub Connecting(Byval sock As Sockets)
      'Right Here is where I need to stop Listening and have the Socket connect
      Socke.Connect(sock) 'Here is where I get the Exception
      connectThread.Abort()
      'Here I need to turn the Listening back on
End Sub

Public Class Sockets : Inherits Socket
Public Port As Integer 
Public IPAddress As IPAddress
Public Clients As New List(Of Sockets)

Public Overloads Sub Connect(Byval sock as Sockets)
     Dim point As New IPEndPoint(DirectCast(socket.LocalEndPoint), IPEndPoint)
     connectDone.Reset()
     BeginConnect(point, AddressOf Callback, sock)
     connectDone.WaitOne()
End Sub

Private Sub Callback(ByVal r As IAsyncResult)
     EndConnect(r)
     connectDone.Set()
End Sub

End Class

【问题讨论】:

A) 您使用的是哪种协议? B) 这个错误发生在哪里? C) 向我们展示您的代码。 @VisualVincent 有帮助吗? 除了我对 x82 的答案的 cmets 之外,我建议您查看我以前的答案之一您到达在两个端点:TCP Client to Server communication. 【参考方案1】:

你的方法是错误的。服务器套接字侦听端口,客户端尝试连接。当从客户端接收到连接时,服务器会创建另一个套接字(当 server.Accept() 返回阻塞套接字时)。

accept 调用的返回值也是一个套接字,你应该使用它来与客户端通信。我对VB不太好,但是你要编码的是你必须保存socket.Accept()的返回值:

clientSocket = server.Accept()

然后您可以在 clientSocket 变量上调用发送/接收方法。

【讨论】:

我班上的每个 Socket 都是一个服务器和一个客户端。它将 Socket 添加到 List 并保持它们的引用,直到它想要向特定的套接字发送连接。 您最好以更清晰的方式告诉我们您想要实现的目标,以便我们提出建议。在我看来,您目前对该问题的解决方案过于复杂。关键是您不必从服务器端连接到客户端,当您从接受调用返回套接字时,服务器和客户端之间已经建立了一个通信通道。你为什么要再次从服务器连接到该客户端(你不能),你应该使用你的客户端列表中的套接字。 @DotNetProgrammer :x82 所说的是正确的。还需要指出的是,TCP 套接字(我不知道 UDP 或其他)只能侦听传入连接是传输数据的实际客户端 ,而不是两者。 @DotNetProgrammer :您应该使用 TcpClientTcpListener 类,而不是使用套接字。它们建立在 Socket 类之上,为您完成所有烦人的工作。

以上是关于套接字侦听和连接的主要内容,如果未能解决你的问题,请参考以下文章

您的服务器套接字侦听积压限制为 100 个连接

在 iPhone 上侦听 CocoaASyncSocket 接收连接但新套接字不调用委托

将套接字传递给新的 AppDomain

如何在 tcp 套接字侦听器中唯一标识套接字 id

通过 WCF 的套接字连接协议 net.tcp 的问题

关闭 OTP 主管拥有的 gen_tcp 侦听套接字