创建C#脚本时,我能够连接到TCP,但无法执行任何命令,如登录等...
执行RQ01,R01,10,CLI,CNUM
的示例命令在旁注上我能够从上面的命令使用PuTTY获得响应,但是无法在C#代码中执行命令。
我的代码:
try {
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
TcpClient client = new TcpClient("xxx.xxx.xx.x", 2131);
var message = "LOGIN,10,SUGARDEV,CLEF";
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
//var message = "LOGIN,10,SUGARDEV,CLEF";
// Translate the passed message into ASCII and store it as a Byte array.
//Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
// Close everything.
//stream.Close();
//client.Close();
} catch (ArgumentNullException e) {
Console.WriteLine("ArgumentNullException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
答案 0 :(得分:0)
首先,您必须选择是否使用异步或同步通信。同步是最简单的,您发送命令并等待响应到达。然后你可以有一个状态机来定义你在沟通过程中的位置:
或者您可以使用异步通信,您可以在其中发送命令并且不等待响应 - 响应将由其他代码处理。然后,您需要在单独的线程中使用RX处理程序,它始终等待传入的数据,并将其发送到某个缓冲区。然后,在发送命令后,您可以继续执行其他操作并稍后再回来查看响应是否已到达。
编辑:我的偏好通常是异步通信,因为它会导致应用程序中的延迟最小。如何实现它取决于通信协议,如果它是,例如ASCII字符串或复杂的二进制协议。
这是来自异步实现的RX处理程序的片段。这是串行通信线路上的二进制协议,因此必须逐个验证每个接收到的字节。
public class Message
{
public Message()
{
Payload = new Payload();
RawData = new List<byte>();
}
public byte Address { get; set; }
public byte Length { get; set; }
public Payload Payload { get; set; }
public byte Checksum { get; set; }
public List<byte> RawData { get; set; }
}
enum RxState
{
AwaitStartCharacter,
AwaitLengthCharacters,
AwaitPayloadCharacters,
AwaitChecksumCharacters
}
private void RxBufferQueueConsumer()
{
var rxState = RxState.AwaitStartCharacter;
Message rxMessage = null;
while (!_cts.IsCancellationRequested)
{
CheckRxBufferQueue(ref rxState, ref rxMessage);
}
}
private BlockingCollection<byte> _rxBufferQueue;
private CancellationTokenSource _cts;
private void CheckRxBufferQueue(ref RxState rxState, ref Message rxMessage)
{
byte rxByte;
if (_rxBufferQueue.TryTake(out rxByte, 50))
{
switch (rxState)
{
case RxState.AwaitStartCharacter:
AwaitStartCharacter(ref rxState, rxByte, ref rxMessage);
break;
case RxState.AwaitLengthCharacters:
AwaitLengthCharacters(ref rxState, rxByte, ref rxMessage);
break;
case RxState.AwaitPayloadCharacters:
AwaitPayloadCharacters(ref rxState, rxByte, ref rxMessage);
break;
case RxState.AwaitChecksumCharacters:
AwaitChecksumCharacters(ref rxState, rxByte, ref rxMessage);
break;
}
}
}