2016-07-15 197 views
0

我設置了一個System.Net.Sockets.Socket。我開始監聽傳入連接的套接字以獲取套接字請求。這個套接字應該能夠停止Listen和寫入並連接到其他套接字。將套接字設置爲Listen後,我無法發送連接命令。我得到這個異常:套接字監聽和連接

「System.InvalidOperationException」類型的未處理的異常出現在 System.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 
+0

** A)**您使用什麼樣的協議? ** B)**這個錯誤發生在哪裏? ** C)**向我們顯示您的代碼。 –

+0

@VisualVincent有幫助嗎? –

+0

除了我對x82的回答的評論之外,當** _你在兩個端點之間傳輸數據時,我建議看到我以前的答案之一_ **:[** TCP客戶端到服務器通信**]( http://stackoverflow.com/a/35240061/3740093)。 –

回答

1

你的方法是錯誤的。服務器套接字在端口上偵聽,並且客戶端嘗試連接。當從客戶端收到連接時,服務器會創建另一個套接字(當server.Accept()在阻塞套接字上返回時)。

該接受調用的返回值也是一個套接字,這就是你應該用來與客戶端進行通信的東西。我不是VB那麼好,但你要什麼樣的代碼是你必須保存的socket.Accept()返回值:

clientSocket = server.Accept() 

,那麼你可以調用發送/接收您clientSocket變量的方法。

+0

我班的每個Socket都是一個Server和一個Client。它將Socket添加到列表中,並將它們保留在引用中,直到它想要將連接發送到特定的套接字爲止。 –

+0

你最好告訴我們你想以更清晰的方式達到什麼樣的目標,所以我們可以提出建議。在我看來,你目前解決這個問題的方法過於複雜。關鍵的一點是,你不必從服務器端連接到客戶端,在你有從accept調用返回的套接字的時候,服務器和客戶端之間已經建立了一個通信通道。爲什麼你很難再從服務器連接到該客戶端(你不能),你應該在客戶端列表中使用套接字。 – x82

+0

@DNet網絡程序員:x82說的是正確的。指出一個TCP套接字(我不知道UDP或其他套接字)只能監聽傳入的連接_或傳輸data_的實際客戶端,而不是兩者。 –