2016-03-17 133 views
0

我目前正在編寫客戶端 - 服務器應用程序。客戶端發送一個UDP廣播消息,試圖定位一個服務器,服務器發送一個UDP廣播消息來標識其位置。使用TCP c將數據包從服務器發送到特定客戶端#

當客戶端收到標識服務器位置的消息時,它會嘗試使用socket.Connect(remoteEndPoint)連接到服務器。

服務器在偵聽套接字上偵聽這些TCP請求,並使用listensocket.accept()接受請求。客戶端詳細信息存儲在陣列中(包括其IP和端口號)

客戶端向服務器發送一條消息,提供有關用戶輸入的用戶名和密碼的信息。

服務器檢查數據庫中的用戶名和密碼,並根據結果向發送請求的客戶端發送TCP消息(這是它的中斷點),以便使用偵聽套接字來檢查U & P.我試圖使用下面的代碼來發送TCP消息,但它不會工作,因爲我得到一個錯誤。

TCPSocket.SendTo(message, clientsArray[i].theirSocket.RemoteEndPoint); 
+0

可以直接調用'Socket.Connect(remoteEndPoint)'和捕獲異常,看看是否您的服務器上使用此服務器已打開。通過這種方式會更簡單。正如我所說的那樣,你可以在代碼中完全刪除UDP的存在。你可以通過clientsArray [i] .theirSocket.Send(msg);'發送給一個連接的客戶端。由於'SendTo'僅在UDP中使用。 – J3soon

+0

我只使用UDP來避免在服務器端使用如此多的資源,因爲UDP無限期地廣播服務器位置不是一個好主意。我知道連接正常,並且服務器處於打開狀態,因爲我可以在客戶端和服務器端看到它(消息出現在GUI上,表示客戶端已連接),並且服務器是否關閉消息出現在客戶端。我試圖發送使用*** TCPSocket.SendTo(message,clientsArray [i] .theirSocket.RemoteEndPoint); ***這是完全相同的,但我得到的錯誤。 – JOsh

+1

我說'SendTo'函數用在** UDP Only **中,所以你只能在我的答案中使用'Send'函數作爲使用TCP **的** Socket。你可以完全忘記'SendTo'函數,因爲你正在使用TCP。 – J3soon

回答

3

我不確定您使用的是什麼方法。

但在C#中有一些可以作爲服務器使用2個普通班:TcpClient & Socket

TcpClient的

... 
//Start Server 
Int32 port = 13000; 
IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 
server = new TcpListener(localAddr, port); 
server.Start(); 

//Accept Client 
TcpClient client = server.AcceptTcpClient();    

NetworkStream stream = client.GetStream(); 
String data = "Message From Server"; 
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data); 

//Send to Client 
stream.Write(msg, 0, msg.Length); 
... 

插座使用TCP

... 
//Start Server 
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0]; 
IPEndPoint ep = new IPEndPoint(hostIP, port); 
listenSocket.Bind(ep); 
listenSocket.Listen(backlog); 

//Accept Client 
Socket handler = listener.Accept(); 

String data = "Message From Server"; 
byte[] msg = Encoding.ASCII.GetBytes(data); 

//Send to Client 
handler.Send(msg); 
... 

並在插座中使用UDP

你不應該因爲你使用的是TCP

... 
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); 
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], 11000); 

Socket s = new Socket(endPoint.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); 

String data = "Message From Server"; 
byte[] msg = Encoding.ASCII.GetBytes(data); 
//Send to Client by UDP 
s.SendTo(msg, endPoint); 
... 
+0

@JOsh這只是一個簡單的示例,用於教授如何使用這些類。真正的服務器不像這樣。服務器將是多線程的,每個客戶端有一個或兩個線程。 – J3soon

+0

因此,您可以創建一個用於接受客戶端的線程,並且在接受客戶端之後,您應該爲連接的客戶端創建一個接收循環線程,並且可能會將該套接字存儲在數組或其他東西中。 – J3soon

+0

當你要發送給客戶端時,你可以從數組中獲取'Socket',並用[SendTo]發送它(https://msdn.microsoft.com/zh-tw/library/eae4f5y0%28v = vs.110%29.aspx)。 – J3soon

0

通常,當你從一個客戶端的連接,你會得到一個TcpClient。該班有一個方法GetStream()。如果你想發送一些數據給客戶端,只需將你想要的數據寫入該數據流即可。

+0

好像它可能是我想要的。我仍然使用Listensocket的sendTo屬性在流上發送數據。我只問,因爲我沒有看到TcpClient的任何sendStream屬性。 – JOsh

+0

在[這裏](https://msdn.microsoft.com/zh-tw/library/eae4f5y0%28v=vs.110%29.aspx)它表示'SendTo'是「發送一個無連接的數據報到指定的遠程主機。」 – J3soon

+0

@JOsh:對於通信,您只需調用GetStream(),然後在給定流上調用所需的讀取和寫入方法(sync或async)。而已。 – Oliver

相關問題