I am trying to communicate with the traffic simulator SUMO with a C# Script. SUMO is launched listening to a port and waits for a client connection. The connection is succesful. Then, I try to make a simulation step, sending the corresponding command, and then receiving the response.
However, when I try to receive the response, my program gets blocked when trying to execute this line:
int i = paramDataInputStream.ReadInt32() - 4;
Where paramDataInputStream
is a BinaryReader
. I understand that this method ReadInt32 is blocking the system because there is no data available to read, which leads me to the conclusion that something of the following is happening:
In SUMO's webpage they define the communication protocol. Is says the following:
A TCP message acts as container for a list of commands or results. Therefore, each TCP message consists of a small header that gives the overall message size and a set of commands that are put behind it. The length and identifier of each command is placed in front of the command. A scheme of this container is depicted below:
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 | |
+--------------------------------------+ /
In the case of the "Simulation Step command", the identifier is 0x02 and the content is just an integer corresponding to the timestep (Click here for more detail).
Before providing some more code regarding the way I send the messages, I have one doubt regarding the way I defined the socket, that is maybe the reason. I looked on the Internet when trying to translate from Java to C# and I found this:
this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
While, in the Java source code, the socket is only defined as follows:
this.socket = new Socket();
Since the communication protocol doesn't look exactly like TCP (the header in my case is one the overall length, while TCP's header is quite more complex), maybe the way I defined the socket is not correct.
If the comments/answers state that this is not the problem, I will update with more code.
I spend the whole day making trials and in the end nothing worked. In the end, I made a very simple code which seems logical to me but doesn't work either:
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);
}
}
The bytes I am sending correspond to: 4 bytes (1 integer) for total length (which is 10 bytes), 1 byte for command length (which is 6 bytes), 1 byte for command identifier (which is 0x02), and 4 bytes (1 integer) for the content of the comand, which is 0 in this case because I want to advance 1 timestep only.
I have sniff the communication to check if the bytes were sent correctly, and I even receive and ACK from SUMO, but the timestep doesn't improve and I don't receive the answer from the Server.
I found the mistake. The error was not in the code, but in the way I launched SUMO. The "steplength" was not initialized, therefore, the timesteps were being done, but the simulation time was not changing because of that.