Reputation: 51
I have a commandsystem to communicate between my TCP Server and Client (Java). I can send specific commands to my Client, if the Client received a command, it will execute something.
Basically, thats working. But sometimes I have to send the command + extra informations. The problem is: The informations will sometimes be sent too fast. So some information will get lost / mixed up and my Client cant execute the request properly.
The solution for me was to use Thread.sleep()
, but this isn't clean nor efficent. Because there is still a risk that the information will not be received properly.
My Server:
public void sendCommand(Socket socket) throws InterruptedException, IOException {
writeMsg("CMD_POPUP", socket);
Thread.sleep(150);
writeMsg("foo", socket);
Thread.sleep(150);
writeMsg("bar", socket);
Thread.sleep(150);
writeMsg("baz", socket);
}
public void writeMsg(String message, Socket socket) throws IOException {
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(message);
}
My Client:
public void interpreteCommand(Socket socket) throws IOException {
while (true) {
switch (readMsg(socket)) {
case "CMD_POPUP":
System.out.println(readMsg(socket));
System.out.println(readMsg(socket)); //Sometimes it would be 'bar' but also sometimes it would be 'baz'
System.out.println(readMsg(socket)); //Sometimes it would be 'baz' but also sometimes it would be nothing
break;
}
}
}
public String readMsg(Socket socket) throws IOException {
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
return in.readUTF();
}
Upvotes: 2
Views: 106
Reputation: 842
First of all, I'm not a java programmer. However tcp connections work the same way in other programming languages.
TCP Connections are stream-based, meaning there is no start or end of a message. The only thing TCP guarantees is that the data is arriving in the right order.
If you send "CMD_POPUP" and "foo" immediately after each other, you don't know if you will receive "CMD_POPUP", "CMD_POPUPfoo", "CMD_PO" etc. on the other side. Because you are waiting a specific amount of time between each send, the data usually does arrive one after each other. But that is not guaranteed and I would also consider this a not very clean way of doing it.
The easiest way to get around this is to send a start character in the beginning, separator characters between the parameters and a end-character after each message. e.g. "#CMD_POPUP%foo%bar$" or sth like that. This way, you can write everything you receive to a buffer until you receive the end of a message, and then process it.
Upvotes: 4
Reputation: 608
Actually you don't need Thread.sleep
instead you can pass extra information appended with the command itself like writeMsg("foo;extrainformation", socket);
and on the other side split this string where first part is command.
Otherwise, Instead of passing the string
you can pass entire object
or json
structure for better implementation.
Upvotes: 3