C# TelNet接收到的数据在每次读取时都有所不同
我有一个小项目要做,这涉及到从TelNet客户端接收输入,并根据输入执行一些处理并将信息返回给客户端 现在我已经完成了大部分工作,线程中有一个侦听器,侦听器接收到的每个客户端都有自己的线程。这工作正常,没有任何错误。当客户机有一些文本输入,并且在我的代码中接收到这些文本时,就会出现问题,我在按一个键一个键的基础上接收到的是正确的,但是当我将其存储在state对象中时,会得到一些奇怪的结果 这是在侦听器接收到新的客户端连接时创建的类,它还用于与TelNet客户端的通信:C# TelNet接收到的数据在每次读取时都有所不同,c#,telnet,stringbuilder,C#,Telnet,Stringbuilder,我有一个小项目要做,这涉及到从TelNet客户端接收输入,并根据输入执行一些处理并将信息返回给客户端 现在我已经完成了大部分工作,线程中有一个侦听器,侦听器接收到的每个客户端都有自己的线程。这工作正常,没有任何错误。当客户机有一些文本输入,并且在我的代码中接收到这些文本时,就会出现问题,我在按一个键一个键的基础上接收到的是正确的,但是当我将其存储在state对象中时,会得到一些奇怪的结果 这是在侦听器接收到新的客户端连接时创建的类,它还用于与TelNet客户端的通信: internal clas
internal class TelNetClient
{
Socket _socket;
public TelNetClient(Socket socket)
{
var t = new Thread(() => RealStart(socket));
t.Start();
}
private void RealStart(Socket socket)
{
this.ClientSocket = socket;
}
public Socket ClientSocket
{
set
{
StateObject stateObject;
DeviceConnection deviceConnection = new DeviceConnection();
_socket = value;
stateObject = new StateObject();
stateObject.WorkSocket = _socket;
Send(_socket, "Welcome");
_socket.BeginReceive(stateObject.Buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallBack), stateObject);
}
}
internal void ReadCallBack(IAsyncResult asyncResult)
{
string content = string.Empty;
int bytesRead;
StateObject stateObject;
DeviceConnection deviceConnection = new DeviceConnection();
stateObject = (StateObject)asyncResult.AsyncState;
bytesRead = _socket.EndReceive(asyncResult);
if (bytesRead > 0)
{
ASCIIEncoding ascii = new ASCIIEncoding();
stateObject.StringBuilder.Append(ascii.GetString(stateObject.Buffer,
0, bytesRead));
content = stateObject.StringBuilder.ToString();
if (content.EndsWith(deviceConnection.BarcodeTerminator))
{
Send(_socket, Environment.NewLine + ">>>>>" + content + "<");
}
else
{
_socket.BeginReceive(stateObject.Buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallBack), stateObject);
}
}
}
internal void Send(Socket socket, string data)
{
Byte[] byteData;
byteData = Encoding.ASCII.GetBytes(data);
socket.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallBack), socket);
}
internal void SendCallBack(IAsyncResult asyncResult)
{
int bytesSent;
Socket socket;
StateObject stateObject;
stateObject = new StateObject();
stateObject.WorkSocket = _socket;
socket = (Socket)asyncResult.AsyncState;
bytesSent = socket.EndSend(asyncResult);
_socket.BeginReceive(stateObject.Buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallBack), stateObject);
}
大部分内容可能不是必需的,但我正在展示所有内容,以便人们能够看到完整的画面
问题在于ReadCallBack
方法,正如您所看到的,我读取字节数组并将其解码为字符串,然后将该字符串附加到StateObject
类中的StringBuilder
。每次解码的值都是正确的,但是当调用stateObject.StringBuilder.ToString()
时,输出是不正确的,但它是100%可预测的。以下是一个例子:
Key Press Count | Input from TelNet Client | StrinBuilder.ToString() Output
---------------------------------------------------------------------------
1 | A | A
2 | B | B
3 | C | AC
4 | D | BD
5 | E | ACE
6 | F | BDF
正如您所看到的,最后一个字符总是正确的,但是前面的字符应该是连接在一起的前一个输入,正如您从StringBuilder
中所期望的那样。在我所有的各种测试中,这种情况100%都会发生。这几乎就像StringBuilder
释放偶数/奇数字符,但在下一次迭代中再次找到它们
我已尝试将StringBuilder
更改为一个string
,但出现了相同的问题
有人知道为什么会发生这种情况以及如何修复吗?您正在创建两个
StateObject
实例:一个在set\u ClientSocket
中,另一个在SendCallback
中。它们最后都作为两个独立的BeginReceive
调用的一部分传递给ReadCallback
。看起来每个实例都在接收其他字符 猜测一下,您可能有两个StateObject
实例,每个实例接收其他字符。无法完全理解您的代码,但您正在set\u ClientSocket
中创建一个StateObject
,并在SendCallback
中创建另一个对象,这两个对象最终都作为两个单独的BeginReceive
调用的一部分传递给ReadCallback
。@pmcoltrane您是对的,与StringBuilder
无关,只与我正在使用的两个StateObject
对象有关!我没有仔细阅读示例代码,这对我来说是正确的。如果您愿意,您可以将您的评论更改为答案,因为这是问题的正确答案。谢谢。我很高兴这有帮助。我已经把我的评论作为一个答案转载并稍作修改。作为一个一般的建议,你应该考虑使用同步套接字API。它们要简单得多。所有这些回调都使问题变得复杂,以至于您很难发现问题。@老实说,该程序的TelNet部分来自另一个开发人员原型,他们已经用实际设备对其进行了测试,所以我知道它是有效的。虽然我想尝试一种更简单的方法,但我对TelNet知之甚少,所以我不想为它做额外的工作,因为当我最终可以用真正的设备测试它时,它就不工作了。
Key Press Count | Input from TelNet Client | StrinBuilder.ToString() Output
---------------------------------------------------------------------------
1 | A | A
2 | B | B
3 | C | AC
4 | D | BD
5 | E | ACE
6 | F | BDF