C# 通过tcp协议向硬件发送命令,networkstream read 读取返回信息时卡死。

2025-03-23 11:57:17
推荐回答(5个)
回答1:

你使用的是telnet协议连接的设备

telnet并不是一个传输层协议 而是一个应用层协议 它是有一些格式上的规定的

比如 在交流前需要互相握手 会发送一些控制字符


你可以使用一些网络包监测工具(比如微软的network monitor)

或者自己创建一个模拟telnet服务器来研究这个包头:

void Main()
{
TcpListener server = new TcpListener(IPAddress.Loopback, 10010);
server.Start();

var client = server.AcceptSocket();
byte[] buffer = new byte[4096];
client.Send(new byte[1]);
while(true) {
int len = client.Receive(buffer);
if (len > 0)
Console.WriteLine("receive byte[{0}] {{{1}}}", len, string.Join(",", buffer.Take(len)));
else
break;
}

server.Stop();
}

在我的机器上 使用putty连接这个服务器 收到的第一个串为

receive byte[21] 
{255,251,31,255,251,32,255,251,24,255,251,39,255,253,1,255,251,3,255,253,3}

你可以查看一些资料来了解这个串的含义

http://tools.ietf.org/html/rfc1572

http://en.wikipedia.org/wiki/Telnet

或者看看这篇blog

http://xu.xue.yi.blog.163.com/blog/static/957382482010582594065/


当进行初始化配置后 才可以进行telnet命令发送阶段。


=======================

一句话。。你连接后少发了个包头_(:з」∠)_

回答2:

我建议你增加一个线程专门用来读取

首先创建一个method
void read()
{
int BL = stream.Read(buffer2, 0, buffer2.Length);
string meg2 = Encoding.ASCII.GetString(buffer2, 0, buffer2.Length);
MessageBox.Show(meg2);
}
然后在原来的地方将卡死语句替换成

Thread thr = new Thread(read);
thr.Start();

当然了,buffer2 这个你要放到外面去定义,并且是public类型的

回答3:

            TcpClient client = new TcpClient();

            try

            {

                client.Connect(hostIp, port);

                NetworkStream ns = client.GetStream();

                ns.ReadTimeout = 3000;

                ns.WriteTimeout = 3000;

                byte[] bs = Encoding.Default.GetBytes(strInfo);

                ns.Write(bs, 0, bs.Length);

                byte[] bytes = new byte[1024];

                int length = ns.Read(bytes, 0, bytes.Length);

                string data = System.Text.Encoding.Default.GetString(bytes, 0, length);

                recData = data;

                client.Close();

                ns.Close();

            }

            catch (Exception ex)

            {

                client.Close();

                recData = ex.Message;

            }

回答4:

一般这个多线程问题。使用多线程处理。你使用单线程,就一直UI无响应。等待方法结束。
子线程不能控制UI。要想控制UI。需要UI做操作,允许子线程操作UI。上面代码messbox。show(“222”)在线程里是弹不出的。直接报错。

回答5:

使用线程等待,增加超时处理