Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TelNet接收到的数据在每次读取时都有所不同_C#_Telnet_Stringbuilder - Fatal编程技术网

C# TelNet接收到的数据在每次读取时都有所不同

C# TelNet接收到的数据在每次读取时都有所不同,c#,telnet,stringbuilder,C#,Telnet,Stringbuilder,我有一个小项目要做,这涉及到从TelNet客户端接收输入,并根据输入执行一些处理并将信息返回给客户端 现在我已经完成了大部分工作,线程中有一个侦听器,侦听器接收到的每个客户端都有自己的线程。这工作正常,没有任何错误。当客户机有一些文本输入,并且在我的代码中接收到这些文本时,就会出现问题,我在按一个键一个键的基础上接收到的是正确的,但是当我将其存储在state对象中时,会得到一些奇怪的结果 这是在侦听器接收到新的客户端连接时创建的类,它还用于与TelNet客户端的通信: internal clas

我有一个小项目要做,这涉及到从TelNet客户端接收输入,并根据输入执行一些处理并将信息返回给客户端

现在我已经完成了大部分工作,线程中有一个侦听器,侦听器接收到的每个客户端都有自己的线程。这工作正常,没有任何错误。当客户机有一些文本输入,并且在我的代码中接收到这些文本时,就会出现问题,我在按一个键一个键的基础上接收到的是正确的,但是当我将其存储在state对象中时,会得到一些奇怪的结果

这是在侦听器接收到新的客户端连接时创建的类,它还用于与TelNet客户端的通信:

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