套接字开始变慢并且没有响应
本文关键字:响应 开始 套接字 | 更新日期: 2023-09-27 18:36:54
我正在开发一个服务器(使用C#)和一个客户端(使用flash,ActionScript 3.0)应用程序。服务器不断向客户端发送数据(数据约为 90 字节),客户端根据它们接收的数据运行(数据为 json 格式)
有一段时间,一切都按预期工作,但一段时间后,客户端开始延迟接收消息。 他们继续等待一段时间,然后根据最后一条消息(一些消息丢失)行事。 一段时间后,客户端开始等待并同时处理所有消息。我不知道是什么原因造成的。我的网络状况稳定。
这是我的 C# 代码的一部分,发送消息:
public void Send(byte[] buffer)
{
if (ClientSocket != null && ClientSocket.Connected)
{
ClientSocket.BeginSend(buffer, 0, buffer.Length, 0, WriteCallback, ClientSocket);
}
}
private void WriteCallback(IAsyncResult result)
{
//
}
和我的客户端的某些部分,接收消息(操作脚本)
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
function onResponse(e:ProgressEvent):void {
trace(socket.bytesAvailable);
if(socket.bytesAvailable > 0) {
try
{
var serverResponse:String = socket.readUTFBytes(socket.bytesAvailable);
....
我希望我能解释我的问题。我应该如何优化我的代码?什么可能导致滞后。谢谢。
你真的需要更详细地说明你是如何设置套接字的(是TCP还是UDP?
假设它是一个 TCP 套接字,那么看起来您的客户端依赖于每个接收调用,返回的字节数与服务器的Send()
调用发送的字节数相同。但是,情况并非如此,如果客户端上仅部分接收消息,或者一次接收多条消息,则很可能是导致问题的原因。
例如,服务器可能在单个调用中发送 90 字节的消息,但您的客户端可能会在一个 90 字节的接收、两个 45 字节的块,甚至 90 x 1 字节的块,或介于两者之间的任何内容中接收它。当客户端收到时,服务器发送的多条消息也可能部分组合。例如,可以在单个 180 字节块中接收两条 90 字节的消息,或者一个 150 字节和一个 30 字节块等。
因此,您需要在消息上提供某种框架,以便在客户端接收数据流时,可以可靠地将其重建为单个消息。
最基本的成帧机制是在发送的每条消息前面加上一个指示消息大小的固定长度字段。 如果您可以保证您的消息永远不会> 255 字节长,则可以使用单个字节,这将简化接收代码。
在客户端,您首先需要接收长度前缀,然后从套接字读取多达这么多字节来构造消息数据。如果收到的字节数少于所需的字节数,则接收代码必须等待更多数据(在最终接收到时将其附加到部分接收的消息中),直到它有完整的消息。
收到完整消息后,可以像您当前一样处理它。
不幸的是,我不了解 ActionScript,所以不能给你一个客户端代码的例子,但以下是你如何用 C# 编写服务器和客户端框架:
服务器端:
public void SendMessage(string message)
{
var data = Encoding.UTF8.GetBytes(message);
if (data.Length > byte.MaxValue) throw new Exception("Data exceeds maximum size");
var bufferList = new[]
{
new ArraySegment<byte>(new[] {(byte) data.Length}),
new ArraySegment<byte>(data)
};
ClientSocket.Send(bufferList);
}
客户端:
public string ReadMessage()
{
var header = new byte[1];
// Read the header indicating the data length
var bytesRead = ServerSocket.Receive(header);
if (bytesRead > 0)
{
var dataLength = header[0];
// If the message size is zero, return an empty string
if (dataLength == 0) return string.Empty;
var buffer = new byte[dataLength];
var position = 0;
while ((bytesRead = ServerSocket.Receive(buffer, position, buffer.Length - position, SocketFlags.None)) > 0)
{
// Advance the position by the number of bytes read
position += bytesRead;
// If there's still more data to read before we have a full message, call Receive again
if (position < buffer.Length) continue;
// We have a complete message - return it.
return Encoding.UTF8.GetString(buffer);
}
}
// If Receive returns 0, the socket has been closed, so return null to indicate this.
return null;
}