#c #sockets #winapi #recv
#c #сокеты #winapi #recv
Вопрос:
у меня есть два проекта: один — клиент, а другой — сервер. допустим, сервер должен отправлять клиенту 2 сообщения одно за другим. клиентский код выглядит следующим образом:
while(1)
{
recv(acceptedStr, socket);
printf("%sn, acceptedStr);
*other code lines*
}
в то время как код сервера выглядит следующим образом:
while(1)
{
send(socket, "First String");
send(socket, "Second String");
*other code lines*
}
если для второй отправки нет ТАЙМ-аута, получит ли recv клиента «Вторую строку»? или он должен убедиться, что он находится в recv перед отправкой сервером?
Комментарии:
1. Вы ожидаете увидеть a
n
после каждой из отправленных строк? Это не гарантируется. При TCP-соединении вы можете получать данные с помощью одногоrecv
или десяти. Обеспечивается только порядок. Не границы между отдельнымиsend
вызовами. Если вы используете UDP, то граница каждой дейтаграммы фиксирована, но вы можете получать их в другом порядке.2. Ваши аргументы вызова send и recv неверны.
3. Вероятно, вам нужен какой-то цикл событий . Рассматривали ли вы возможность использования libevent или GTK ?
Ответ №1:
Нет, принимающая сторона не должна иметь recv
активный для send
работы.
После установления соединения данные буферизуются сетевым стеком операционной системы. И recv
завершится успешно после поступления данных и send
завершится успешно, если данные были доставлены в сетевой стек получателя.
Ответ №2:
Ответ на ваш вопрос
Да, этого достаточно, и ваш код будет работать. Но если вы хотите расширить его больше, или если сервер и клиент должны быть синхронизированы все время, продолжайте чтение.
Синхронизация сервера и клиента
Прочитайте это, если вы хотите синхронные операции сервера и клиента.
Я ранее работал с send и recv, и я бы посоветовал вам одну вещь: вы всегда чередуете recv и send дополнительными способами. В качестве примера
Сервер:
send()
recv()
send()
.
.
.
Клиент:
recv()
send()
recv()
.
.
.
Обычно отслеживать это утомительно. (Я думаю, что вызывается обратная отправка от объекта на recv ack
).
Но в какой-то момент вы хотели бы повернуть поток событий. Для этого вы можете просто отправить и восстановить некоторые случайные данные.
Ранее я написал оболочку вокруг send и recv для своего проекта. Не стесняйтесь проверить это: https://github.com/ArenaGrenade/Simple-FTP-Server/blob/main/utils.cpp . (Это довольно хорошо документировано, поэтому, даже если вы не поняли мое объяснение, вы бы поняли то, что в коде.)
Дайте мне знать, если вы поняли, отметив мое как ответ. Рад помочь! Если у вас есть сомнения, просто прокомментируйте ниже. 🙂
Комментарии:
1. Где ваш комментарий? @alk
2. Я удалил его. Я не ответил на вопрос.
3. Нет проблем! Сделайте upvote, если вы считаете это правильным. Спасибо.
Ответ №3:
Клиент действительно получает Second String
, но он работает не так, как вы думаете.
Я создал клиент и сервер с помощью двух официальных образцов: полного кода клиента Winsock и полного кода сервера Winsock
Я изменил образец так, чтобы сервер только отправлял данные, а клиент только получал данные.
Когда я пытаюсь отправить данные два раза подряд, клиент получит следующее содержимое:
Вы можете видеть, что клиент действительно получает Second String
, но поскольку вы продолжаете отправлять эти два данных, это вызовет проблемы на картинке.
Поскольку данные отправляются непрерывно, клиент также будет получать данные, отправленные несколько раз за один раз, и сохранять их в один и тот же буфер, хотя отображается только его часть (поскольку она усекается на ‘ 0’), но это видно по размеру буферачто данные, отправленные несколько раз, принимаются одновременно.И содержимое, полученное позже, будет непредсказуемым