recv вернется, когда во внутренних буферах будут данные для возврата. Он не будет ждать, пока не будет 100 байт, если вы запросите 100 байт.
Если вы отправляете 100-байтовые «сообщения», помните, что TCP не предоставляет сообщения, это просто поток. Если вы имеете дело с сообщениями приложения, вам нужно обработать это на уровне приложения, так как TCP этого не сделает.
Существует множество условий, при которых вызов send () длиной 100 байт может не считываться полностью на другом конце, если при вызове recv (..., 100) используется только один вызов recv; Вот только несколько примеров:
Отправляющий стек TCP решил связать воедино 15 вызовов записи, и MTU оказался равным 1460, что - в зависимости от синхронизации поступивших данных может привести к тому, что первые 14 вызовов клиентов получат 100 байтов и 15. вызов для извлечения 60 байтов - последние 40 байтов появятся при следующем вызове recv (). (Но если вы вызываете recv с буфером 100, вы можете получить последние 40 байтов предыдущего сообщения «application» и первые 60 байтов следующего сообщения)
Буферы отправителя заполнены, возможно, устройство чтения медленное или сеть перегружена. В какой-то момент данные могут пройти, и при очистке буферов последний кусок данных не был кратным 100.
Буферы получателя заполнены, в то время как ваше приложение recv () для этих данных, последний извлекаемый им фрагмент является лишь частичным, поскольку целые 100 байтов этого сообщения не помещаются в буферы.
Многие из этих сценариев довольно сложно протестировать, особенно на локальной сети, где у вас может не быть большой перегрузки или потери пакетов - вещи могут отличаться, когда вы увеличиваете или уменьшаете скорость, с которой сообщения отправляются / производятся.
Во всяком случае. Если вы хотите прочитать 100 байтов из сокета, используйте что-то вроде
int
readn(int f, void *av, int n)
{
char *a;
int m, t;
a = av;
t = 0;
while(t < n){
m = read(f, a+t, n-t);
if(m <= 0){
if(t == 0)
return m;
break;
}
t += m;
}
return t;
}
...
if(readn(mysocket,buffer,BUFFER_SZ) != BUFFER_SZ) {
//something really bad is going on.
}