Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача структуры через сокет 
:(
    Опции темы
drZmeu
Дата 28.3.2007, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 22.11.2006

Репутация: 1
Всего: 1



А можно примерчик  smile 
А то у меня уже мозги закипают  smile 
--------------------
[code=html]<table bgcolor='#0' width='69'><tr align='center' bgcolor='#0'><td><font size='6' face='cursive' color='#ffffff'><b>A</b></font></td></tr><tr align="center" bgcolor="#0">[/code]
PM MAIL   Вверх
leniviy
Дата 5.6.2007, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



У меня вопрос. Может ли команда recv разбить принимаемую структуру на несколько частей. Например, я точно знаю, что сервер мне послал 10 байт. Может ли первый вызов recv вернуть меньше 10? Я пока от неуверенности , пользую эту функцию
Код

    int recvExactly(SOCKET s, char* buf, int len, int flags)
    {
        int result;
        char* buf1 = buf;
        while(buf1-buf < len)
        {
            result = ::recv(s, buf1, len, flags);
            if ((result==SOCKET_ERROR)||(result==0)) return result;
            buf1 += result;
            len -= result;
        }
        return (int)(buf1-buf);
    }

PM MAIL   Вверх
ptr
Дата 6.6.2007, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Да, recv возвращает только то, что пришло на данный момент. Поэтому количество байт может быть не больше того, что было затребовано.

P.S. если хочешь задать какой-нибудь вопрос, то лучше для этого создавать новую тему. Тем более что вопрос никак не связан с текущей темой.

Это сообщение отредактировал(а) ptr - 6.6.2007, 15:11


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
intel
Дата 13.9.2007, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



После тово как получил структуру по сокету и запихал её в буфер, хочу привести тот самый буфер к типу структуры, 
но компилятор кричит "так не пойдёт". Не пойму где я там касяк спорол

Вот кусок кода:
Код

char buf[256];

int rc = recv(s,buf,sizeof(buf),0);

if( rc <= 0 )
    cout<<"recv error"<<endl;

else
    cout<<((Data)buf).x;

А вот мой тип (подключаю в голове):
Код

class Data {
    public:
        int x;
        int y;
};

Спасибо
PM MAIL   Вверх
leniviy
Дата 14.9.2007, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



((Data*)&buf)->x
PM MAIL   Вверх
intel
Дата 14.9.2007, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Спасибо leniviy, всё получилось
PM MAIL   Вверх
intel
Дата 17.9.2007, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Вот ещё небольшая проблемка.

по сокету отправляю структуру в сторону клиента, но тот ничего не получает, хотя блок else  выполняется. 
В структуре int и указатель на char. 

Вообщем вот кусок от server'а:
Код

Message myMessage;
myMessage.messageType   = REGISTER;
myMessage._message      = "hallo\0";

int rs = send(client[i],(const char*)&myMessage,sizeof(myMessage),0);


А вот от клиента:
Код

char buf[256];

if( rr <= 0 )
    cout<<"recv error"<<endl;

else {
    cout<<"recv OK"<<endl;
    buf[rr] = '\0';
    cout<<((Message*)&buf)->_message;
}

Ну и моя структура до кучи:
Код

struct Message {
    char *_message;
    int messageType;
};

Вот что выходит на консоль (у клента):
Код

Connect OK
Recv OK


Сдаётся мне там чтото с char'ом не то...
PM MAIL   Вверх
dumb
Дата 17.9.2007, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



Цитата(intel @  17.9.2007,  21:25 Найти цитируемый пост)
Сдаётся мне там чтото с char'ом не то...
правильно сдается - ты пересылаешь указатель на строку, а не саму строку.

структура должна быть примерно такого вида:
Код

#pragma pack(push,1)
struct Message {
    int messageType;
    int messageLen;
    char _message[0];
};
#pragma pack(pop)
...
// пример подготовки и отсылки
char s[] = "hallo";
int len=strlen(s);
Message *msg = (Message*)new char[sizeof(Message)+len+1];
msg->messageType = 0;
msg->messageLen = len;
strcpy(msg->_message, s)
send(client[i],(const char*)msg, sizeof(Message)+len+1,0);
delete[] (char*)msg;
...


и при получении надо учитывать тот момент, что данные, отосланные одним вызовом send, вовсе не обязательно придут одним куском - вполне возможно их нужно будет читать несколькими вызовами recv.
PM MAIL   Вверх
intel
Дата 18.9.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Спасибо dumb, скопировал твой предложенный вариант, заработало как по маслу, 
вот тока не въеду што значят #pragma pack(push,1) и #pragma pack(pop)? 
В гугле ничево не нарыл, поясни если не затруднит
PM MAIL   Вверх
Artemon
Дата 19.9.2007, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


Профиль
Группа: Завсегдатай
Сообщений: 1771
Регистрация: 24.2.2004
Где: Челябинск

Репутация: 1
Всего: 20



Все так весело передают структуры по сокетам, даже не задумываясь о выравнивании струкуры в памяти.

Только лишь dumb не стал этим принебрегать (на то он и эксперт).

#pragma pack(push,1) - отменяет выравнивание.


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
mrbrooks
Дата 20.9.2007, 15:14 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: нет
Всего: 306



Комрады если уж сыр - бор про передачу инфы через сокеты - то как насчет юзанья структуры WSANETWORKEVENTS. А именно что бы сохранить инфу от сервера на клиенте скажим хотя бы в файл. Кто нибудь посоветует что нибудь? Пжаста!

Это сообщение отредактировал(а) mrbrooks - 20.9.2007, 15:15
PM MAIL   Вверх
dumb
Дата 20.9.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 1
Всего: 158



Цитата(mrbrooks @  20.9.2007,  16:14 Найти цитируемый пост)
как насчет юзанья структуры WSANETWORKEVENTS. А именно что бы сохранить инфу от сервера на клиенте скажим хотя бы в файл.
какая связь между словами в этих предложениях?
PM MAIL   Вверх
mrbrooks
Дата 21.9.2007, 08:17 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: нет
Всего: 306



Цитата(dumb @ 20.9.2007,  23:13)
какая связь между словами в этих предложениях?

TCP/IP
PM MAIL   Вверх
Skladnoy
Дата 21.9.2007, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 13.9.2007

Репутация: нет
Всего: нет



Цитата(Artemon @  19.9.2007,  13:01 Найти цитируемый пост)
Все так весело передают структуры по сокетам, даже не задумываясь о выравнивании струкуры в памяти.

А еще int может иметь разный размер, разную endianness... Вообще говоря.
PM MAIL   Вверх
BasilL
Дата 12.12.2008, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 26.5.2005
Где: Челябинск обл.

Репутация: нет
Всего: 1



Приветствую!
Не стал создавать новую тему - спрошу здесь

имеем структуру
Код

struct Message
    {
            AnsiString MsgType;
            AnsiString MsgIP;
            AnsiString MsgText;
    };
Message MsgRecv;
Message MsgSend;


передаем
Код

MsgSend.MsgType = "0004";
MsgSend.MsgIP = inet_ntoa(new_sa.sin_addr);
MsgSend.MsgText = MsgText_;
int length = MsgSend.MsgType.Length() + MsgSend.MsgIP.Length() + MsgSend.MsgText.Length() + 1;
if (SOCKET_ERROR == (send(clnt.socket, (const char*)&MsgSend, length, 0 ) ) )
{
// Error...
int error = WSAGetLastError();
ErrorMessage(error);      // ...
// ...
}


принимаем
Код

ret = recv(wParam, (char*)&MsgRecv, 1024, 0); // 1024 - макс. размер


все передается и принимаеться нормально. Но далее происходит вот что
Код

if (MsgRecv.MsgType == "0100")
{
// обработка
}

Как только выполнение программы приходит на строку с if ((MsgRecv.MsgType) == "0100") условие срабатывает... Хотя в принятом MsgRecv.MsgType = "0004"... Смотрю в отладчике - да, все принимается ок, MsgType = "0004". Программа переходит на строку с проверкой условия - и MsgType становится равно "0100".... Пробовал менять значения в условии - что бы ни поставил, всегда MsgType становится равным ему... Как будто в if-е не "==" стоит, а "="....
В чем может быть дело?

Это сообщение отредактировал(а) BasilL - 12.12.2008, 23:11
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0871 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.