Ваша оригинальная идея не сработает.recv()
будет блокироваться, если он прочитал все отправленные байты, если и до тех пор, пока не будут отправлены еще некоторые.Если никто не будет отправлен, вы застряли.Как указывалось выше, вам нужен какой-то способ узнать, когда вы достигли конца передачи.
Есть два пути, по которым вы могли бы пойти.Самый простой способ - просто закрыть сокет на отправляющей стороне, когда вы отправили все данные.recv()
затем вернет 0 в должное время, и вы знаете, что все ожидаемые вами данные получены.
Другой, несколько более сложный способ - это отправить длину сообщения перед самим сообщением.Это достаточно просто.На отправляющей стороне (проверка ошибок для краткости опущена):
uint32_t msg_len = ...;
uint32_t network_byte_order_msg_len = htonl (msg_len);
int nbytes = sizeof (network_byte_order_msg_len);
sendall (skt, sizeof (uint32_t), &network_byte_order_msg_len, &nbytes);
nbytes = msglen;
sendall (skt, my_msg_buf, &nbytes);
И на принимающей стороне, предполагая, что у нас есть функция recv_bytes
, которая вызывает в цикле recv
, пока не получит количество байтовон ищет:
uint32_t network_byte_order_msg_len;
int nbytes = sizeof (network_byte_order_msg_len);
recv_bytes (skt, &network_byte_order_msg_len, nbytes);
int msg_len = ntohl (&network_byte_order_msg_len);
void *msg_buf = malloc (msg_len);
nbytes = msg_len;
recv_bytes (skt, msg_buf, &nbytes);
Обратите внимание, что, поступая таким образом, мы можем сразу же выделить в приемнике буфер сообщений правильного размера, что приятно и эффективно.
Вы в порядке, чтобы написать recv_bytes()
?Отредактируйте реализацию в моем сообщении, если хотите, для будущих посетителей.
Редактировать: Этот код - C ++, я уверен, что вы можете это исправить.