Страницы

Поиск по вопросам

понедельник, 10 февраля 2020 г.

Какие типы данных и в каком виде можно передавать через TCP bsd socket?

#cpp #c #сокет #tcp


Во всех примерах использования bsd сокетов на си для передачи и приема информации
используется массив символов фиксированной длинны char buff[255]. Например read(socketFD,
buff, sizeof(buff));. Возникает пара вопросов:


Обязательно ли использовать массив char, или же можно передавать произвольные объекты?
например можно ли передать double buff[255] или даже struct someStructType buff[255]?
Что будет, если отправить массив например в 200 элементов, а на принимающей стороне
считать только 100? При повторном чтении мы прочитаем те же элементы, или же следующие
100 элементов?

    


Ответы

Ответ 1



В сокет передаются исключительно байты, что бы ваши объекты превратить в байты или создать их из них нужно использовать протоколы сериализации, такие как например T-L-V или ProtoBuf. В примерах приводится массив-буфер для считывания в него информации, как правило функция чтения возвращает реальное количество считанных байт. Если вы отправите 200 байт, а считаете 100, то вам надо будет считать потом еще 100. Буфер может быть любого размера (но как правило его делают не более MTU/MRU). Как правило при обмене данными через сеть, они упаковываются в пакет вида: packetLength:packetData, что позволяет гарантированно считывать переданный пакет. Так, например, отправляя 200 байт нужной информации вы: Считываете в буфер приема данные из сокета. Читаете из этого буфера длину пакета packetLenght (сколько байт - зависит от типа переменной и архетиктруры); Создаете буфер размером packetLength. Это не тот же самый буфер в который вы читаете из сокета!! Копируете из буфера приема данные в созданный буфер, при этом если размер данных меньше, чем осталось в буфере, то копируете нужно кол-во, если больше, то пишите все, а затем дочитываете далее из сокета в буфер приема до тех пор, пока не вытащите все.

Ответ 2



Первый, по сути, вопрос переносимости. Вы просто передаете блок байтов. Нужны гарантии корректной интерпретации их с другой стороны. Вдруг там другой порядок байтов? Другой формат данных? Или еще что-то? Вот поэтому и используется максимально обобщенный вариант - просто сколько-то байтов. Что касается структур - то учтите еще и выравнивание. Надеюсь, чем чревата передача просто объектов в духе string s; write(fd, &s, sizeof(s)); вы понимаете? :) А то некоторые ухитряются... Второй - прочтете при следующем чтении остальные 100 байтов. Если, конечно, до того не закроете соединение :)

Комментариев нет:

Отправить комментарий