Обычно это результат чего-то вроде:
/* BAD CODE */
const char* ack = "ACK";
err = write( sockfd, ack, strlen( ack )); /* sender */
/* ... */
char buf[SOME_SIZE]
readb = read( sockfd, buf, SOME_SIZE ); /* receiver */
printf( "%s", buf );
Проблема с кодом выше заключается в том, что отправитель записывает только три (3) байта в сокет.Это не включает в себя строку нулевого терминатора.Затем получатель получает данные и либо вообще не проверяет возвращаемое значение системного вызова, либо / и слепо печатает полученные данные.printf
будет печатать все, пока не найдет нулевой байт в памяти.
Редактировать:
Основываясь на ваших комментариях, я думаю, вы предполагаете, что один send(2)
через сокет TCP должен получиться один recv(2)
на другом конце с соответствующим количеством байтов (я предполагаю, что это то, что вы подразумеваете под "числом прочитанных байтов, которое является неправильным").Это не в случае с TCP, хотя.Вы должны рассматривать сокет как поток, который может дать вам куски произвольного размера того, что было отправлено вам.Ваша задача собрать их вместе и распознать границы сообщений приложения.Это просто означает, что вы всегда читаете из сокета в цикле (не считая неблокирующих проектов с select(2)
и друзьями - это отдельная тема).
Два принятых протокола уровня приложенияВозможны следующие варианты:
- Связь через предопределенные сообщения фиксированной длины - так вы будете читать, пока не получите столько байтов из сокета.Простой.
- Включение типа сообщения и / или длины сообщения в само сообщение - обычно это делается с заголовком сообщения фиксированной длины, за которым следует различная полезная нагрузка сообщения.Читайте, пока не получите полный заголовок, затем переключите / отправьте / продолжайте чтение в зависимости от типа / длины.
Не забывайте о endianess - сети, такие как сетевой порядок байтов .