我正在尝试使用 C# 脚本与交通模拟器 SUMO 进行通信。SUMO 启动侦听端口并等待客户端连接。连接成功。然后,我尝试做一个模拟步骤,发送相应的命令,然后接收响应。
但是,当我尝试接收响应时,我的程序在尝试执行此行时被阻止:
int i = paramDataInputStream.ReadInt32() - 4;
paramDataInputStream
一个在哪里BinaryReader
。我知道这种方法 ReadInt32 正在阻塞系统,因为没有可读取的数据,这使我得出以下结论:正在发生以下情况:
- 命令未正确发送。
- 套接字定义不明确
- 因为我拿了一些Java代码并试图翻译它,也许有一些错误
在SUMO 的网页中,他们定义了通信协议。是这样说的:
TCP 消息充当命令或结果列表的容器。因此,每条 TCP 消息都包含一个小的标头,该标头给出了整个消息的大小和一组放在它后面的命令。每个命令的长度和标识符放在命令的前面。该容器的示意图如下所示:
0 7 8 15
+--------------------------------------+
| Message Length including this header |
+--------------------------------------+
| (Message Length, continued) |
+--------------------------------------+ \
| Length | Identifier | |
+--------------------------------------+ > Command_0
| Command_0 content | |
+--------------------------------------+ /
...
+--------------------------------------+ \
| Length | Identifier | |
+--------------------------------------+ > Command_n-1
| Command_n-1 content | |
+--------------------------------------+ /
以“仿真步长命令”为例,标识为0x02,内容为时间步长对应的整数(点击这里查看更多详细信息)。
在提供更多关于我发送消息的方式的代码之前,我对我定义套接字的方式有一个疑问,这可能是原因。尝试从 Java 转换为 C# 时,我在 Internet 上查看,发现:
this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
而在Java源代码中,socket只定义如下:
this.socket = new Socket();
由于通信协议看起来并不完全像 TCP(在我的情况下,标头是总长度之一,而 TCP 的标头要复杂得多),也许我定义套接字的方式不正确。
如果评论/答案表明这不是问题,我将使用更多代码进行更新。
编辑
我花了一整天的时间进行试验,最后没有任何效果。最后,我做了一个非常简单的代码,这对我来说似乎是合乎逻辑的,但也不起作用:
public static void step(NetworkStream bw, int j)
{
byte[] bytes = { 0, 0, 0, 10, 6, 2, 0, 0, 0, 0 };
bw.Write(bytes, 0, bytes.Length);
bw.Flush();
}
public static void Main(String[] argv)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.NoDelay = true;
try
{
socket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 60634));
}
catch (Exception localConnectException)
{
Console.WriteLine(localConnectException.StackTrace.ToString());
}
NetworkStream ns = new NetworkStream(socket);
//BinaryWriter bw = new BinaryWriter(ns); (I tried with both, BinaryWriter and NetworkStream and the result was the same
for (int i = 0; i < 100; i++)
{
step(ns,i);
}
}
我发送的字节对应:4字节(1个整数)总长度(10字节),1字节命令长度(6字节),1字节命令标识符(0x02),4字节(1 个整数)用于命令的内容,在这种情况下为 0,因为我只想提前 1 个时间步长。
我已经嗅探通信以检查字节是否正确发送,我什至从 SUMO 接收和确认,但时间步长没有改善,我没有收到服务器的答案。