TCP Socket快速报文发送

本文关键字:报文 Socket TCP | 更新日期: 2023-09-27 18:01:48

我有一个类的登录客户端:

public class LoggedIn_Class
{
    public Socket socket;
    public string name;
}

我有一个列表:

public static List<Object> LoggedIn_List = new List<Object>();

当有人登录到我的服务器时,我将其添加到列表中:

LoggedIn_Class newClient = new LoggedIn_Class();
newClient.socket = currentSocket;
newClient.name = currentName;
LoggedIn_List.Add(newClient);

现在我试着向每个客户端发送一个数据包:

foreach (LoggedIn_Class s in variables.LoggedIn_List.ToArray())
{
   s.socket.Send(Packet);
}

现在的问题是foreach处理太快的项目,它不能发送。这工作正常,但我不认为这是最好的解决方案…

foreach (LoggedIn_Class s in variables.LoggedIn_List.ToArray())
{
   s.socket.Send(Packet);
   Thread.Sleep(50);
}

有人知道这个吗?我能做些什么来等待发送结束?

TCP Socket快速报文发送

我使用TCP套接字。客户端只是没有收到数据包,没有任何异常。

关于这个问题有很多答案。你真正的问题是你没有理解基于流的协议意味着什么。使用TCP时,您不发送消息,而是发送字节流。

因此,接收方不能假设在一个socket.Receive中接收到的所有内容与另一方使用socket.Send发送的所有内容对应完全相同的字节。

因此,您应该使用某种机制来检测何时接收到完整的消息。通常,您可以在每条消息前加上长度前缀,或者在每条消息后使用分隔符。

当你使用Thread.Sleep时,它工作的原因是消息足够短,可以一次发送一个,并且你可以在发送下一个消息之前接收它们。如果没有延迟,nagle算法可能会发挥作用并合并你的消息。

幼稚的实现:

public void Send(byte[] msg)
{
    var header = BitConverter.GetBytes(msg.Length);
    socket.Send(header, 0, header.Length);
    socket.Send(msg, 0, msg.Length);
}

接收端(可能有故障,但应该给你一个提示):

var buffer = new byte[4];
int bytesReceived = socket.Receive(buffer, 0, 4, ....);
if (bytesReceived < 4)
{
     bytesReceived = socket.Receive(buffer, bytesReceived, 4 - bytesReceived, ....);
     //this can fail too, probably should use a loop like below until
     //all four length bytes have been received.
}
var bytesToRead = BitConverter.GetInt32(buffer, 0);
var buffer = new byte[bytesToRead];
var offset = 0;
while (bytesToRead  > 0)
{
   var len = Math.Min(bytesToRead, buffer.Length);
   var read = socket.Receive(buffer, offset, len, .....);
   bytesToRead -= read;
   offset += read;
}
//now you got everything.