我写了一个TCP服务器来接收来自多个iOS客户端的消息。但是,它只接收第一条TCP消息并停止接收后续消息。问题是什么?
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8060);
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipadr = IPAddress.Parse("10.10.10.10");
System.Net.IPEndPoint EndPoint = new System.Net.IPEndPoint(ipadr, 8060);
newsock.Bind(EndPoint);
newsock.Listen(255);
while (true)
{
Socket client = newsock.Accept();
recv = client.Receive(data,SocketFlags.None);
if (recv == 0)
break;
string receivedText = Encoding.ASCII.GetString(data, 0, recv);
Console.Write(receivedText);
}
newsock.Close();
答案 0 :(得分:3)
循环中有Accept
。您只想接受任何给定的连接一次,然后循环Receive
以获取数据。
如果您希望能够同时处理多个客户端,则会变得有点复杂。一种方法是为每个客户端创建一个线程。这允许您继续使用阻止Receive
并使每个进度或多或少地独立进行。当每个消息的处理花费大量时间并且客户端数量相当小时,这可能会有所帮助。另一种方法是使用非阻塞I / O.您可以将Blocking
设置为false,以便Receive
立即完成,即使没有可用数据,然后遍历所有活动连接以检查新数据。或者您可以使用BeginReceive
并异步执行操作。请注意,即使您在单个线程中执行所有接收,您仍然可以通过将接收的消息存储在工作队列中并使用工作线程池来处理数据,从而在多个线程中处理它们。
您使用术语消息,好像暗示接收的数据具有某种大于字节的结构。准备失望。 TCP保证在连接的一端推入的字节将以相同的顺序出现在另一端并且没有重复。无法保证它们是如何分组的,即如果您输入六个500字节的“消息”,则可能会收到一个3000字节的块或任何的各种较小的分组,最多可添加3000个字节。状态机对于从片段重组消息非常有用。我通常使用固定长度的消息头,其中包括整个消息长度以简化过程。一旦你有足够的字节来拥有一个完整的消息头,那么你可以处理标题。这为您提供了整体消息长度,以便您可以从缓冲区中提取它或等到收到剩余部分。