我有一个登录客户端的类:
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);
}
有人对此有任何想法吗?我该怎么做才能等待发送结束?
答案 0 :(得分:2)
我正在使用TCP套接字。客户端只是没有收到数据包,没有任何例外。
关于此,有很多答案。你真正的问题是你还没有理解基于流的协议意味着什么。使用TCP,您不发送消息,您发送字节流。
因此,接收方不能假设在一个socket.Receive
中收到的所有内容与使用socket.Send
发送的另一方完全相同的字节。
因此,您应该使用某种机制来检测何时收到完整的消息。通常,您可以使用长度前缀为每条消息添加前缀,也可以在每条消息后使用分隔符。
当您使用Thread.Sleep
时,它的工作原理是,消息足够短,一次只能发送一个消息,并且您可以在发送下一条消息之前设置接收消息。没有延迟,nagle algorithm可能会发挥作用并合并您的消息。
天真的实施:
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.