我在使用简单的TCP读/写应用程序时出现问题,我需要将命令写入设备/主机。通常我可以使用stream.Write()命令执行此操作,但是对于此特定设备,它似乎在发送任何命令之前发回初始欢迎消息(PJLINK 0)。我可以使用PuTTY发送命令,但在使用C#时,我认为我的连接正在关闭,然后才能完成命令。
所以我的问题是如何在没有TcpClient提前关闭连接的情况下调整下面的代码来接收欢迎消息,然后发回命令(我不需要阅读响应)?
非常感谢任何帮助。
using (tcpClientA = new TcpClient())
{
int portA = 4352;
if (!tcpClientA.BeginConnect("10.0.2.201", portA, null, null).AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1.0)))
{
throw new Exception("Failed to connect.");
}
while (tcpClientA.Connected)
{
using (streamA = tcpClientA.GetStream())
{
if (type == "raw")
{
// Buffer to store the response bytes.
byte[] writeBufferC = Encoding.ASCII.GetBytes("%1 INPT 32$0D"); //Command I need to send
byte[] readBufferC = new byte[tcpClientA.ReceiveBufferSize];
string fullServerReply = null;
using (var writer = new MemoryStream())
{
do
{
int numberOfBytesRead = streamA.Read(readBufferC, 0, readBufferC.Length);
if (numberOfBytesRead <= 0)
{
break;
}
writer.Write(writeBufferC, 0, writeBufferC.Length);
} while (streamA.DataAvailable);
fullServerReply = Encoding.UTF8.GetString(writer.ToArray());
Console.WriteLine(fullServerReply.Trim());
}
}
}
}
}
更新1 删除了BeginConnect和Async方法。
using (tcpClientA = new TcpClient())
{
int portA = 4352;
tcpClientA.Connect("10.0.2.201", portA);
while (tcpClientA.Connected)
{
using (streamA = tcpClientA.GetStream())
{
if (type == "raw")
{
byte[] readBufferC = new byte[tcpClientA.ReceiveBufferSize];
byte[] writeBufferC = Encoding.ASCII.GetBytes("%1 INPT 31$0D"); //Command I need to send
string fullServerReply = null;
using (var writer = new MemoryStream())
{
do
{
streamA.Read(readBufferC, 0, readBufferC.Length); //First read
writer.Write(writeBufferC, 0, writeBufferC.Length); //Send command
} while (streamA.DataAvailable);
fullServerReply = Encoding.UTF8.GetString(readBufferC.ToArray());
Console.WriteLine(fullServerReply.Trim());
tcpClientA.Close();
}
}
}
}
}
答案 0 :(得分:0)
DataAvailable
未告诉您远程端将来会发送多少数据。它的使用几乎总是一个bug。在这里,它会让你提前随机退出循环。
读取,直到您拥有所需的所有字节或直到关闭流。
这是一个基于行的协议吗?实例化StreamReader
并从流中绘制整行。
while (tcpClientA.Connected)
什么也没做。即使它返回true,连接也可能在1纳秒之后丢失。无论如何,你的代码必须处理它。它应该是while (true)
。这不是一个错误,它只是显示了弱的TCP理解,所以我指出它。
删除ReceiveBufferSize
的所有用法。这个值意味着没有意义。而是使用固定的缓冲区大小。我发现4096可以很好地处理吞吐量不高的连接。
numberOfBytesRead <= 0
应为==0
。同样,不是一个错误,但你似乎并不清楚API的作用。这很危险。
在更新的代码中,您没有使用streamA.Read
的返回值,这是一个错误。您已尝试通过修剪生成的\0
字符来修复该错误。这只是治疗症状而不是真正的解决方法。
您需要一个套接字教程。这场大屠杀是因为你不依赖最佳实践。如果做得好,套接字读取循环实际上相当简单。此代码是可能出错的集合。