2016-03-17 198 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

相关问题