sizeof
возвращает размер объекта. В этом случае не весь этот объект фактически используется, но sizeof
не волнует. Всегда возвращает размер объекта. С
char sendBuf[1024] = "Hello";
sizeof(sendBuf)
всегда 1024, независимо от того, сколько символов используется. Это значит
send(s, sendBuf, sizeof(sendBuf), 0);
отправляет "Hello\0"
вместе с другими 1018 неопределенными байтами (уверен, что это будут все нулевые символы благодаря инициализации char sendBuf[1024] = "Hello";
, но не может найти стандартную цитату, чтобы доказать это.) В sendbuf. Этот код повторяется 4 раза для общего количества отправленных 4096 байт. Мой .Net шаткий, но
byte[] recvBuf = new byte[100];
conn.Receive(recvBuf);
получит до 100 байтов. Это Привет и набор пустых символов. Вам нужно будет прочитать 10.24 из них, чтобы пройти через все дополнительные нули и найти следующий Hello .
так первый
message = System.Text.Encoding.UTF8.GetString(recvBuf);
удается распечатать Hello , но следующие три не видят ничего, кроме 100 байтов нулевых символов.
Решение:
Отправляйте только то, что вам нужно.
char sendBuf[1024] = "Hello";
sendResult = send(s, sendBuf, strlen(sendBuf), 0); // send all characters up to the
// first null character
или
char sendBuf[] = "Hello"; // buffer will be sized to fit string(including null)
sendResult = send(s, sendBuf, sizeof(sendBuf), 0);
Оговорка:
TCP / IP - это потоковый протокол. Он не имеет понятия отдельных сообщений и радостно смешивает отдельные вызовы на send
в один пакет или несколько пакетов, как требуется. Это означает, что при первом получении могут быть возвращены все четыре Hello s.
Кроме того, получатель никогда не знает, что он собирается получить с данным чтением сокета TCP. Сообщение, возможно, было разделено на два пакета, чтобы максимизировать пропускную способность, и один из этих пакетов мог быть перенаправлен на большие расстояния и быть недоступным, когда клиент читает сообщение.
Вам потребуется установить и использовать протокол связи, чтобы дифференцировать ваши сообщения. При отправке строк я предпочитаю отправлять размер строки в целое число известного размера и порядковый номер, а затем отправлять строку. Получатель считывает длину (и проверяет, что он получил всю длину, прежде чем продолжить) строки, а затем считывает байты длины (снова не больше, не меньше), чтобы получить строку.