V
V
Vermut7562016-12-11 14:02:06
C++ / C#
Vermut756, 2016-12-11 14:02:06

TCP: is it true that send/write cannot be called from different threads, otherwise the contents of the buffers will be mixed up?

I am building a rather complex client-server system, so I would like to use multithreading, say on the client in one thread to send a heartbeat, and in the other - a command to the server, and at the same time use only one socket.
But is this a good solution?

First, let me explain what kind of confusion I'm talking about.

So here is the pseudo code I am posting:

send("123456"); // Поток 1
send("ABCDEF");  // Поток 2


I know that in the end, the receiving side may come like this:
ABCDEF
123456


That is, I understand that the order of the messages themselves that I send can be confused.
When I tried to create a lot of threads, I observed this , so it really is.
And I'm not afraid of it.

But one person on the forum, if I understand him correctly, claims that things are even worse.
He says that supposedly the bytes themselves in the messages can get mixed up, that is, this can also come:
ABC45F
123DE6


Is it true?
When I tried to create many streams, I did NOT observe this, there were many messages, but none of them mixed bytes with bytes from other messages.
But I will not hope for a chance, so just in case I ask.

Operating system:
Windows, different versions and bit depths, but only Windows, both on the server and on the clients.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
S
sitev_ru, 2016-12-11
@sitev_ru

Add mutexes:

mutex my_mutex;
void my_send() {
  my_mutex.lock();
  // тут отправляем в сокет
  my_mutex.unlock();
}
void my_recv() {
  my_mutex.lock();
  // тут читаем из сокета
  my_mutex.unlock();
}

Write these commands both on the server and on the client

L
lega, 2016-12-11
@lega

If the cache is used at the OS level, and not at the application level, then everything will be ok.
For reliability and error reduction, you can make the 3rd stream for sending, and add all the data to send to it.

1
15432, 2016-12-11
@15432

On short messages (less than MTU) this will not happen. Now, if you send several kilobytes in one of the streams, a situation may arise when parts of the messages are mixed up.
Example:
- thread 1 sends 10000 bytes, send returned 2048
- thread 2 writes a short command to the same socket at the same time
- thread 1 sends the remaining bytes, but the command from thread 2 has already climbed in front of them
Why not add mutexes? Or multiple sockets?

V
Vladimir Dubrovin, 2016-12-12
@z3apa3a

The content in send() / write() should not be confused, because the output is not buffered, the function is executed in one system call. But send () / write () in any case can send not a full data buffer, it is necessary to control the returned value. And resend the unsent. Since one command may have to be sent in several send() / write() operations, the content in different streams may be mixed up. True, in practice this (sending an incomplete buffer) has never happened to me in Windows (but in POSIX systems this is a fairly common occurrence). But, of course, you should not rely on this, and it is better, as already mentioned, to use critical sections or mutexes to synchronize data sending.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question