| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > разные типы данных в сокет |
| Автор: knopka 17.11.2008, 01:27 |
сообщение передаваемое в сокет состоит из двух частей:
Скажите пожалуйста как это лучше сделать Заранее спасибо |
| Автор: Andrey44 17.11.2008, 08:06 |
| Создай структуру, и ее передавай. |
| Автор: knopka 17.11.2008, 09:16 |
| Я так и делал, но со структурой приходит несколько символов, а должно быть явно больше, идеальным для меня было бы передача в формате вектор <char> но немогу сконвертировать структуру хотя бы в char |
| Автор: mrbrooks 17.11.2008, 09:27 |
| knopka, ты бы код выложил. Достаточно твоего буфера и функций send(), recv(). |
| Автор: REZiaMIX 17.11.2008, 09:59 | ||||
Должно быть приблизительно так(в полупсевдокоде
Или более гибкий вариант:
При передаче строки надо учитывать что она прийдет без \0. |
| Автор: knopka 17.11.2008, 12:06 | ||||
| to REZiaMIX Спасибо за помощь.
а как обработать ответное сообщение? вид сообщения: �▒��趣��pW�������� первые четыре это len? а остальные string как их извлечь из буфера? Добавлено через 6 минут и 2 секунды а после отправки надо делать
|
| Автор: REZiaMIX 17.11.2008, 15:03 | ||||||||||||||
len - длина поля string , без нулевого символа.
Тут делаем с a.string что надо (но учесть что она без '\0')
Да , надо. Объясню поподробней. В гибком варианте идет расчет , что при получении пакета мы сначала считаем len, len - длина поля string , без нулевого символа. А потом считываем len байтов , в итоге получим все ,что было отправлено. То что я написал - просто для наглядности и понятия что надо делать. Приблизительный код будет таким , но тк я не тестировал возможны ошибки. Просто надо понять что структура пакета: len char 4 байта len*char байтов Поле len вноситься чтобы сервер знал , какой длины сообщение string. При этом клиент должен соответственно заполнять поле len длиной string Сам до конца не понял , но наверное надо использовать для структур правильное выравнивание , иначе возможны ошибки:
|
| Автор: knopka 17.11.2008, 15:57 |
| В том и загвоздка , что вопрос я упростил вопрос. len у меня в задаче хранит всю длинну сообщения включая несколько полей uint и string |
| Автор: REZiaMIX 17.11.2008, 16:06 | ||||
А зачем хранить длину полей фиксированной длины?
Здесь мы должны знать len, чтобы считать string, а: адрес val1 = sizeof(len)+ len; val2 = sizeof(len)+ len + sizeof(val1); Простая арифметика) |
| Автор: knopka 17.11.2008, 16:09 | ||
а разве len это не длинна поле string? мы ведь нигде не добавляем к длинне сообщения ещё и размер самого поля uint Добавлено через 2 минуты и 58 секунд А если структуру преобразоватьв vector это не упростит задачу? Добавлено через 11 минут и 19 секунд С адресами я понял, а как из буфера (char*)&a прочитать значение для первого поля структуры? |
| Автор: REZiaMIX 17.11.2008, 16:46 | ||||||||
len - длина поля string , уже писал. передавать vector думаю не лучшая идея a - обычная структура , с ней и работать надо как со структурой)
|
| Автор: knopka 17.11.2008, 17:11 | ||
то есть при приёме
структура будет заполнена автоматически? |
| Автор: REZiaMIX 17.11.2008, 19:17 | ||||||||||
Все поля , которые имеют неопределенный размер(в нашем случае string) надо както отдельно обрабатывать. Опечатка , там точка:
Тут мы получим размер поля , для последующего считывания string. далее считаем string
Если в структуре все поля имеют фикс. размер , то:
Автоматически заполнит всю структуру. |
| Автор: knopka 18.11.2008, 15:47 |
| Чё -то сообщение пустое |
| Автор: REZiaMIX 18.11.2008, 16:14 | ||
Чье? |
| Автор: bsa 18.11.2008, 17:32 | ||
knopka, если пишешь на С++, то можно сделать примерно так:
|
| Автор: knopka 18.11.2008, 19:33 | ||||
to REZiaMIX
от сервера на сервере обработка эхом
стандартное построение классов Socket - ClientSocket - SimpleClientMain а в клиенте после приема ответ все поля у структуры а пустые |
| Автор: knopka 18.11.2008, 19:56 | ||
| to bsa не нашёл описания
я так понимаю преобразует тип поля в <char*>? а нельзя как то посимвольно перечитать структуру в вектор? (в смысле конвертировать) буду пробовать и этот вариант |
| Автор: REZiaMIX 18.11.2008, 20:08 | ||
А зачем посылать 3 инта отдельно?) |
| Автор: REZiaMIX 18.11.2008, 21:08 | ||||
| Дабы закончить эту тему: Сервер:
Клиент:
Писал на коленках , но компилируется и работает 100%. Клиент посылает 3 числа и строчку. Сервер увеличивает числа на 1 , меняет строчку и отвечает. |
| Автор: knopka 19.11.2008, 00:11 | ||||||||
| to REZiaMIX спасибо только не пойму где компилить судя по
в винде, попробовал в CodeBlocks и в VisualStudio ошибки и ещё вопрос
почему два раза посылаем, сначала цифры а потом строку? Добавлено через 14 минут и 17 секунд to REZiaMIX Я Вас наверно уже достал ну ещё вопрос А в Linux есть альтернатива
|
| Автор: REZiaMIX 19.11.2008, 12:06 | ||||||||||||||||||
conio.h используется для _getch(); можно заменить чемнить другим и избавиться от заголовка.
Т.к. string в данном случае в структуре - указатель на 0 символ строки. Если послать структуры целиком , то вместо строки пошлем указатель на нее , что не верно. Сначала посылаем 3 инта структуры(val1,val2,val3) + uint(len)
потом посылаем строку.
Наверное не правильный выход , но прокатит это:
Вообще в никсах посмотри описание WSAStartup и подгони тип данных. |
| Автор: bsa 20.11.2008, 11:54 | ||||||||
|
| Автор: knopka 20.11.2008, 18:19 |
| Большое спасибо to REZiaMIX и bsa очень помогли вопрос закрыт |
| Автор: REZiaMIX 20.11.2008, 19:17 | ||
Хм , ну если здесь пишем клиент , то выравнивание задать можем , значит можем быть уверенны) Вообще , нужно знать что нужно знать протокол клиент<->сервер , чтобы таких вопросов не возникало) Думаю в данном случае оба решения подойдут) |
| Автор: knopka 20.11.2008, 19:34 |
| ДА оба подходят |
| Автор: J0ker 20.11.2008, 20:26 |
| все вышенаписанное для TCP соединения на прием работать НЕ БУДЕТ т.к. фрагментация |
| Автор: REZiaMIX 21.11.2008, 08:25 | ||
Хм , поясни , у меня все работает как ни крути |
| Автор: bsa 21.11.2008, 10:23 |
| Кстати, мой вариант работать точно не должен - в описании recv написано, что в случае если полученные данные не помещаются в буфер - излишек теряется. Таким образом действительно надо делать все через вектор... |
| Автор: REZiaMIX 22.11.2008, 12:26 | ||
В данном случае просто рассматривается логика протокола(т.е. все в идеальном состоянии) , а фрагментирование это уже другой разговор. |
| Автор: J0ker 22.11.2008, 17:26 | ||||
фрагментация относится как раз к логике протокола TCP идеального состояния тут не существует - фрагментация может быть даже на локальной машине |
| Автор: REZiaMIX 23.11.2008, 11:54 | ||
Идеально состояние - нет потери пакетов , отсутствие фрагментации , но тут суть в том. Если вместо вызова recv подставить функцию , обеспечивающую склейку пакетов и тд , то этот подход будет работать как надо в любых предусмотренных случаях P.S. Сотый пост) |