C# 异步Telnet服务器数据接收问题
我正在使用C# 异步Telnet服务器数据接收问题,c#,sockets,asynchronous,protocol-buffers,C#,Sockets,Asynchronous,Protocol Buffers,我正在使用异步Begin/End方法编写一个telnet服务器。我面临的问题是确定缓冲区中哪些是实际数据,哪些不是。网络编码对我来说有点陌生,但我一直在努力研究这个问题,却没有找到答案 public bool Start(IGame game) { // Get our server address information. IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName()); IPEndPoint s
异步Begin/End
方法编写一个telnet服务器。我面临的问题是确定缓冲区中哪些是实际数据,哪些不是。网络编码对我来说有点陌生,但我一直在努力研究这个问题,却没有找到答案
public bool Start(IGame game)
{
// Get our server address information.
IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Any, this.Port);
// Instance the server socket, bind it to a port and begin listening for connections.
this._ServerSocket = new Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this._ServerSocket.Bind(serverEndPoint);
this._ServerSocket.Listen(this.MaxQueuedConnections);
this._ServerSocket.BeginAccept(new AsyncCallback(Connect), this._ServerSocket);
return true;
}
private void Connect(IAsyncResult result)
{
var player = new BasePlayer();
try
{
player.Game = this.Game;
player.Connection = this._ServerSocket.EndAccept(result);
lock (this.Connections)
{
this.Connections.Add(player);
}
// Pass all of the data handling for the player to itself.
player.Connection.BeginReceive(player.Buffer, 0, player.BufferSize, SocketFlags.None, new AsyncCallback(player.ReceiveData), player);
// Fetch the next incoming connection.
this._ServerSocket.BeginAccept(new AsyncCallback(Connect), this._ServerSocket);
}
catch (Exception)
{
}
}
然后是播放器。接收数据
public void ReceiveData(IAsyncResult result)
{
int bytesRead = this.Connection.EndReceive(result);
if (bytesRead > 0)
{
// TODO: Parse data received by the user.
//Queue the next receive data.
this.Connection.BeginReceive(this.Buffer, 0, this.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveData), this);
var str = System.Text.Encoding.Default.GetString(Buffer);
}
else
{
this.Disconnect(result);
}
}
因此,当我调用BeginReceive
时,我需要提供一个预定大小的缓冲区。这样做,我的缓冲区数组中就有了未使用的字节。它们的值都是0,所以我假设我可以在数组中循环,并从索引0开始构建一个新的数组,直到达到值0为止
我想有更好的办法吗?有人能给我指出一个正确的方向吗?我应该如何确定缓冲区中有哪些数据,或者我可以不必使用预先确定的缓冲区大小就可以这样做
因此,当调用开始接收时,我需要提供一个预定大小的缓冲区。这样做,我的缓冲区数组中就有了未使用的字节。它们的值都是0,所以我假设我可以在数组中循环,并从索引0开始构建一个新的数组,直到达到值0为止
不,那不是你应该做的。相反,在您的回调(ReceiveData
)中,您已经在调用—结果是您读取的字节数。这就是你应该使用多少缓冲区
但是,在再次调用BeginReceive
之前,应将已读取的数据从缓冲区中复制出来,否则可能会导致下一位数据在开始使用之前覆盖刚刚读取的数据
比如:
string text = Encoding.ASCII.GetString(Buffer, 0, bytesRead);
Connection.BeginReceive(this.Buffer, 0, this.BufferSize, SocketFlags.None,
new AsyncCallback(ReceiveData), this);
我不建议您使用
编码。默认情况下,
将字节转换为文本-相反,您应该决定使用哪种编码,并坚持使用。如果您使用的编码并不总是每个字符一个字节,那么您最终会遇到一个稍微棘手的情况,因为这样您可能会收到一个包含部分字符的缓冲区。在这一点上,您需要保持一个可以保持部分字符读取状态的状态。我可能不太清楚我当时是怎么说的。我是指调用BeginReceive时,所需的参数用于设置大小的缓冲区。@JohnathonSullinger:是的,这是一个要求-就像调用Stream.Read
。在我的ReceiveData
中,我实际上已经调用EndReceive并捕获缓冲区大小(尽管我没有意识到该值是什么)。为了澄清我最初的一些问题,如果我的缓冲区中有数据,并且我得到了EndReceive读取的字节数,有没有办法将我现有的缓冲区拆分成一个新数组,只提取接收到的字节?我想知道是否有类似于byte[]receivedData=this.buffer.Range[0,receivedDataSize]
@JohnathonSullinger:你可以创建一个新数组(newbyte[size]
),然后使用array.Copy
或Buffer.BlockCopy
复制数据。框架中没有实现这一点的现有方法,但是您可以轻松地创建自己的方法。但是,既然要将其转换为字符串,为什么不直接使用Encoding.GetString(byte[],int,int)
?