【发布时间】:2017-06-13 02:26:14
【问题描述】:
我正在尝试训练自己,我目前正在构建一个小型 Tcp 服务器/客户端。
目前我有 3 个连接、监听客户端和监听消息的小类。以下是 3 个类:
public class ServersLauncher
{
#region Main
public static void Main(string[] args)
{
ServersLauncher sl = new ServersLauncher();
Console.ReadLine();
sl._udpServer?.Dispose();
sl._tcpServer?.Dispose();
}
#endregion Main
private UdpServer _udpServer;
private TcpServer _tcpServer;
private ServersLauncher()
{
_tcpServer = new TcpServer();
Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 25004);
sc.Bind(localEndPoint);
IPEndPoint distantEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 25000);
sc.Connect(distantEndPoint);
while (!sc.Connected)
Thread.Sleep(1000);
byte[] buffer = Utility.ConvertMessage("Hell world !");
sc.Send(buffer, buffer.Length, SocketFlags.None);
sc.Close();
}
}
顶部是服务器启动器,它启动服务器、创建客户端并发送消息。
public class TcpServer : IDisposable
{
private readonly int _portTcp = 25000;
private Socket _socket;
private Thread _connectionsThread;
private List<TcpClient> _clients;
public TcpServer()
{
_clients = new List<TcpClient>();
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), _portTcp);
_socket.Bind(endPoint);
_connectionsThread = new Thread(new ThreadStart(ListenConnections));
_connectionsThread.Start();
}
public void Dispose()
{
_connectionsThread.Abort();
for(int i = 0; i < _clients.Count; i++)
{
_clients[i].Dispose();
}
_socket.Close();
}
private void ListenConnections()
{
_socket.Listen(100);
while (true)
{
Socket clientSocket = _socket.Accept();
_clients.Add(new TcpClient(clientSocket));
}
}
}
顶部是 TcpServer,它侦听连接并在一个客户端连接时创建客户端接口。
public class TcpClient : IDisposable
{
private Socket _client;
private Thread _receiverThread;
public TcpClient(Socket client)
{
_client = client;
_receiverThread = new Thread(ReceiveMessage);
_receiverThread.Start();
}
public void Dispose()
{
_receiverThread.Abort();
}
private void ReceiveMessage()
{
while (true)
{
byte[] buffer = new byte[1024];
_client.Receive(buffer);
Utility.DisplayThread("A message has been received : " + Encoding.ASCII.GetString(buffer).Trim());
}
}
}
这里是存储套接字客户端和侦听消息的 TcpClient。 没什么复杂的,但我在阅读邮件时遇到了问题。现在,如果我启动程序,客户端会连接,然后......不停的消息!我收到一个“地狱世界”,然后是空消息。我阅读了 Socket 的 Receive 方法的文档,似乎它应该阻塞并等待消息追求是例行的。 我在某处做错了吗?在断开连接之前我需要从客户端刷新流吗? 感谢您的帮助!
【问题讨论】:
-
在尝试编写网络代码之前,您需要花一些时间研究网络的工作原理。一个好的起点是Winsock Programmer’s FAQ。它不是特定于 .NET 的,但 .NET API 只是 Winsock 上的一个薄层,甚至您需要的大部分信息和记录在案的还有更多关于 Internet 上常用的协议、TCP 和 UDP 的信息特别是关于 Winsock。
-
在你上面的代码中,问题是你懒得看
Receive()返回的值。当它返回 0 时,连接已断开,您应该停止尝试接收。当它返回 0 以外的值时,您实际上应该 使用 该值来确定 实际 发送了多少字节,以便确保只处理刚刚收到的缓冲区。 -
好吧,我的错,应该更深入地寻找文档。谢谢!