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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> разные типы данных в сокет, как передать в одном сообщении 
V
    Опции темы
knopka
Дата 17.11.2008, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



сообщение передаваемое в сокет состоит из двух частей:
  • заголовка из  нескольких unsigned int полей 
  •  и текста
всё это должно передаваться в одном сообщении
Скажите пожалуйста как это лучше сделать 
Заранее спасибо

PM MAIL ICQ   Вверх
Andrey44
Дата 17.11.2008, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Создай структуру, и ее передавай.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
knopka
Дата 17.11.2008, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Я так и делал, 
но со структурой приходит несколько символов, а должно быть явно  больше,
идеальным для меня было бы передача в формате вектор <char> 
но немогу сконвертировать структуру хотя бы в char
PM MAIL ICQ   Вверх
mrbrooks
Дата 17.11.2008, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



knopka, ты бы код выложил. Достаточно твоего буфера и функций send(), recv(). 
PM MAIL   Вверх
REZiaMIX
Дата 17.11.2008, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Должно быть приблизительно так(в полупсевдокодеsmile ):
Код

struct packet{
char string[512];
}a;
recv(socket,(char*)&a,sizeof(a),NULL);
// отправка так
strcpy(a.string,"hello world!!!");
send(socket,(char*)&a,sizeof(a),NULL);

Или более гибкий вариант:
Код

struct packet{
uint len;
char*string;
}a;
recv(socket,(char*)&a,len,sizeof(a.len),NULL);
a.string = new char[a.len];
... обработка
delete [] a.string;
// отправка
char string[] = "Hello World!!!";
a.string = new char[strlen(string)];
strcpy(a.string,string);
a.len = strlen(string);
send(socket,(char*)&a,sizeof(a),NULL);

При передаче строки надо учитывать что она прийдет без \0.

Это сообщение отредактировал(а) REZiaMIX - 17.11.2008, 10:13


--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 17.11.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



to REZiaMIX 
Спасибо за помощь.
Цитата

... обработка

а как обработать ответное сообщение?
вид сообщения: �▒��趣��pW��������
первые четыре это len? а остальные string как их извлечь из буфера?

Добавлено через 6 минут и 2 секунды
а после отправки надо делать 
Цитата

delete [] a.string;

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


Опытный
**


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

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



Цитата(knopka @ 17.11.2008,  12:06)
to REZiaMIX 
Спасибо за помощь.

а как обработать ответное сообщение?
вид сообщения: �▒��趣��pW��������
первые четыре это len? а остальные string как их извлечь из буфера?

Добавлено @ 12:12
а после отправки надо делать 
Цитата

delete [] a.string;

Цитата

первые четыре это len? а остальные string как их извлечь из буфера?

len - длина поля string , без нулевого символа.
Цитата

... обработка

Тут делаем с a.string что надо (но учесть что она без '\0')
Цитата

а после отправки надо делать 
Цитата

delete [] a.string;


Да , надо.

Объясню поподробней.
В гибком варианте идет расчет  , что при получении пакета мы сначала считаем len, len - длина поля string , без нулевого символа.
А потом считываем len байтов , в итоге получим все  ,что было отправлено.
То что я написал - просто для наглядности и понятия что надо делать. Приблизительный код будет таким , но тк я не тестировал возможны ошибки.
Просто надо понять что структура пакета:
len                     char
4 байта             len*char байтов
Поле len вноситься чтобы сервер знал , какой длины сообщение string.
При этом клиент должен соответственно заполнять поле len длиной string

Сам до конца не понял , но наверное надо использовать для структур правильное выравнивание , иначе возможны ошибки:
Код

#pragma pack(push, 1)

struct { /* ... */ };

#pragma pack(pop)



Это сообщение отредактировал(а) REZiaMIX - 17.11.2008, 15:06


--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 17.11.2008, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



В том и загвоздка , что вопрос я упростил вопрос.
len у меня в задаче хранит всю длинну сообщения включая
несколько полей uint  и string
PM MAIL ICQ   Вверх
REZiaMIX
Дата 17.11.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(knopka @ 17.11.2008,  15:57)
В том и загвоздка , что вопрос я упростил вопрос.
len у меня в задаче хранит всю длинну сообщения включая
несколько полей uint  и string

А зачем хранить длину полей фиксированной длины?
Код

struct packet
{
uint len;
char * string
uint val1;
uint val2;
}a;


Здесь мы должны знать len, чтобы считать string, а:
адрес val1 = sizeof(len)+ len;
val2 = sizeof(len)+ len + sizeof(val1);

Простая арифметика)

Это сообщение отредактировал(а) REZiaMIX - 17.11.2008, 16:07


--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 17.11.2008, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата

a.len = strlen(string);

а разве len это не длинна поле string?
мы ведь нигде не добавляем к длинне сообщения ещё и размер самого поля uint

Добавлено через 2 минуты и 58 секунд
А если структуру преобразоватьв vector это не упростит задачу?

Добавлено через 11 минут и 19 секунд
С адресами я понял, а как из буфера (char*)&a
прочитать значение для первого поля структуры? 

PM MAIL ICQ   Вверх
REZiaMIX
Дата 17.11.2008, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(knopka @ 17.11.2008,  16:09)
Цитата

a.len = strlen(string);

а разве len это не длинна поле string?
мы ведь нигде не добавляем к длинне сообщения ещё и размер самого поля uint

Добавлено @ 16:12
А если структуру преобразоватьв vector это не упростит задачу?

Добавлено @ 16:20
С адресами я понял, а как из буфера (char*)&a
прочитать значение для первого поля структуры?

len - длина поля string , уже писал.
передавать vector думаю не лучшая идея smile
a - обычная структура , с ней и работать надо как со структурой)

Код

struct packet
{
uint len;
char * string
uint val1;
uint val2;
}a;

Код

a.packet
a.string
a.val1
a.val2



--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 17.11.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



то есть при приёме
Код

recv(socket,(char*)&a,len,sizeof(a.len),NULL);
 
структура будет заполнена автоматически?
PM MAIL ICQ   Вверх
REZiaMIX
Дата 17.11.2008, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(knopka @ 17.11.2008,  17:11)
то есть при приёме
Код

recv(socket,(char*)&a,len,sizeof(a.len),NULL);
 
структура будет заполнена автоматически?

Все поля , которые имеют неопределенный размер(в нашем случае string) надо както отдельно обрабатывать.
Опечатка , там точка:
Код

recv(socket,(char*)&a.len,sizeof(a.len),NULL);
 
Тут мы получим размер поля , для последующего считывания string.
далее считаем string
Код

recv(socket,(char*)&a.string,a.len,NULL);

Если в структуре все поля имеют фикс. размер , то:
Код

recv(socket,(char*)&a,sizeof(a),NULL);

Автоматически заполнит всю структуру.




--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 18.11.2008, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Чё -то сообщение пустое
PM MAIL ICQ   Вверх
REZiaMIX
Дата 18.11.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(knopka @ 18.11.2008,  15:47)
Чё -то сообщение пустое

Чье?


--------------------
user posted image
PM MAIL   Вверх
bsa
Дата 18.11.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



knopka, если пишешь на С++, то можно сделать примерно так:
Код
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

struct Header
{
    int field1;
    int field2;
    int field3;
//...
    std::string text;
    void send(int socket) const {
        send(socket, reinterpret_cast<const char*>(&field1), sizeof(field1), NULL);
        send(socket, reinterpret_cast<const char*>(&field2), sizeof(field2), NULL);
        send(socket, reinterpret_cast<const char*>(&field3), sizeof(field3), NULL);
//...
        unsigned textSize = text.size();
        send(socket, reinterpret_cast<const char*>(&textSize), sizeof(textSize), NULL);
        send(socket, text.data(), textSize, NULL);
    }
    void recv(int socket) const {
        recv(socket, reinterpret_cast<char*>(&field1), sizeof(field1), NULL);
        recv(socket, reinterpret_cast<char*>(&field2), sizeof(field2), NULL);
        recv(socket, reinterpret_cast<char*>(&field3), sizeof(field3), NULL);
//...
        unsigned textSize;
        recv(socket, reinterpret_cast<char*>(&textSize), sizeof(textSize), NULL);
        std::vector<char> tmp(textSize);
        recv(socket, &*tmp.begin(), textSize, NULL);
        text.clean();
        std::copy(tmp.begin(), tmp.end(), std::back_inserter(text));
    }
};

PM   Вверх
knopka
Дата 18.11.2008, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



to REZiaMIX

Цитата

Чё -то сообщение пустое 


от сервера 

на сервере обработка эхом
Код

a mess;

new_sock >> mess;//получили
new_sock << mess;//отослали 


стандартное построение классов Socket - ClientSocket - SimpleClientMain 

 а в клиенте  после приема ответ все поля у структуры а пустые
PM MAIL ICQ   Вверх
knopka
Дата 18.11.2008, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



to bsa

не нашёл описания 
Цитата

reinterpret_cast

я так понимаю преобразует тип поля в <char*>?

а нельзя как то посимвольно перечитать структуру в вектор? (в смысле конвертировать)

буду пробовать и этот вариант
PM MAIL ICQ   Вверх
REZiaMIX
Дата 18.11.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @ 18.11.2008,  17:32)
knopka, если пишешь на С++, то можно сделать примерно так:

А зачем посылать 3 инта отдельно?)


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 18.11.2008, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Дабы закончить эту тему:
Сервер:
Код

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#pragma comment(lib,"ws2_32.lib")

SOCKET my_sock;
#pragma pack(push, 1)
struct packet
{
    int val1;
    int val2;
    int val3;
    unsigned int len;
    char *string;
    void pcsend(SOCKET to)
    {
        printf("Send:\nval1=%i\nval2=%i\nval3=%i\nlen=%i\nstring=%s\n",val1,val2,val3,len,string);
        send(to,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        send(to,string,len,NULL);
        delete [] string;
    }
    void pcrecv(SOCKET from)
    {
        recv(from,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        string = new char[len+1];
        recv(from,string,len,NULL);
        string[len] = '\0';
        printf("Recv:\nval1=%i\nval2=%i\nval3=%i\nlen=%i\nstring=%s\n",val1,val2,val3,len,string);
        val1++;
        val2++;
        val3++;
        delete [] string;
    }
};

#pragma pack(pop)
#pragma pack(pop)

#define SERVERADDR "127.0.0.1"

int main(int argc,char*argv[])
{
    unsigned int port = 5432;
    SOCKADDR_IN serverSockAddr;
    SOCKADDR_IN clientSockAddr;
    SOCKET serverSocket;
    SOCKET clientSocket;
    int addrLen=sizeof(SOCKADDR_IN);
    WSAData wd;
    WSAStartup(0x202,&wd);
    serverSocket=socket(AF_INET, SOCK_STREAM, 0);
    memset(&serverSockAddr, 0, sizeof(serverSockAddr));
    serverSockAddr.sin_port=htons(port);
    serverSockAddr.sin_family=AF_INET;
    serverSockAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    bind(serverSocket,
        (LPSOCKADDR) &serverSockAddr,
        sizeof(serverSockAddr));

    listen(serverSocket, 1);

    clientSocket=accept(serverSocket,
        (LPSOCKADDR) &clientSockAddr,
        &addrLen);
    char string[] = "Hello client!!!";
    packet tosend;
    tosend.pcrecv(clientSocket);
    tosend.len = strlen(string);
    tosend.string = new char[tosend.len+1];
    strcpy(tosend.string,string);
    tosend.pcsend(clientSocket); 
    _getch();
}


Клиент:
Код

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#pragma comment(lib,"ws2_32.lib")
SOCKET my_sock;
#pragma pack(push, 1)
struct packet
{
    int val1;
    int val2;
    int val3;
    unsigned int len;
    char *string;
    void pcsend(SOCKET to)
    {
        printf("Send:\nval1=%i\nval2=%i\nval3=%i\nlen=%i\nstring=%s\n",val1,val2,val3,len,string);
        send(to,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        send(to,string,len,NULL);
        delete [] string;
    }
    void pcrecv(SOCKET from)
    {
        recv(from,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        string = new char[len+1];
        recv(from,string,len,NULL);
        string[len] = '\0';
        printf("Recv:\nval1=%i\nval2=%i\nval3=%i\nlen=%i\nstring=%s\n",val1,val2,val3,len,string);
        val1++;
        val2++;
        val3++;
        delete [] string;
    }
};

#pragma pack(pop)

#define SERVERADDR "127.0.0.1"

int main(int argc,char*argv[])
{
    unsigned int port = 5432;

    WSAData wd;
    WSAStartup(0x202,&wd);
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(port);
    HOSTENT *hst;


    if (inet_addr(SERVERADDR)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
      if (hst=gethostbyname(SERVERADDR))
          ((unsigned long *)&dest_addr.sin_addr)[0]=
            ((unsigned long **)hst->h_addr_list)[0][0];

    connect(my_sock,(sockaddr *)&dest_addr,
                    sizeof(dest_addr));

    char string [] = "Hello Server!!!";        
    packet tosend;
    tosend.val1 = 666;
    tosend.val2 = 1;
    tosend.val3 = -1;
    tosend.len = strlen(string);
    tosend.string = new char[tosend.len+1];
    strcpy(tosend.string,string);
    tosend.string[tosend.len] = '\0';
    
    tosend.pcsend(my_sock);
    tosend.pcrecv(my_sock); 
    _getch();
}



Писал на коленках , но компилируется и работает 100%. Клиент посылает 3 числа и строчку. Сервер увеличивает числа на 1 , меняет строчку и отвечает.


--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 19.11.2008, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



to REZiaMIX

спасибо только не пойму где компилить 

судя по 
Цитата

#include <conio.h>

 в винде, попробовал в CodeBlocks и в VisualStudio ошибки

и ещё вопрос
Цитата

Код

send(to,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        send(to,string,len,NULL);


почему два раза посылаем, сначала цифры а потом строку?

Добавлено через 14 минут и 17 секунд
to REZiaMIX

Я Вас наверно уже достал ну ещё вопрос

А в Linux есть альтернатива
Код

WSAData 


PM MAIL ICQ   Вверх
REZiaMIX
Дата 19.11.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

судя по 
Цитата

#include <conio.h>

 в винде, попробовал в CodeBlocks и в VisualStudio ошибки

conio.h используется для _getch();
можно заменить чемнить другим и избавиться от заголовка.

Цитата

и ещё вопрос
Цитата

Код

send(to,(char*)this,sizeof(int)*3 + sizeof(unsigned int),NULL);
        send(to,string,len,NULL);


почему два раза посылаем, сначала цифры а потом строку?

Т.к. string в данном случае в структуре - указатель на 0 символ строки.
Если послать структуры целиком , то вместо строки пошлем указатель на нее , что не верно.
Сначала посылаем 3 инта структуры(val1,val2,val3) + uint(len)
Код

sizeof(int)*3 + sizeof(unsigned int)

потом посылаем строку.
Цитата


А в Linux есть альтернатива
Код

WSAData 



Наверное не правильный выход , но прокатит это:
Код


    char buff[1024];
    WSAStartup(0x202,(WSADATA *) &buff[0]);

Вообще в никсах посмотри описание WSAStartup и подгони тип данных.

Это сообщение отредактировал(а) REZiaMIX - 19.11.2008, 12:10


--------------------
user posted image
PM MAIL   Вверх
bsa
Дата 20.11.2008, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(knopka @ 18.11.2008,  19:56)
to bsa

не нашёл описания 
Цитата

reinterpret_cast

я так понимаю преобразует тип поля в <char*>?
reinterpret_cast это преобразование одного типа в другой. Используется, когда не работают static_cast и dynamic_cast. Это стандартные "преобразователи" C++. В принципе, можно написать и (const char*)&field1, но это устаревшая (для С++) форма записи.
Цитата(knopka @ 18.11.2008,  19:56)
а нельзя как то посимвольно перечитать структуру в вектор? (в смысле конвертировать)
Можно и структуру "конвертировать" в вектор, а нужно ли? Но мне показалось это лишним в данном месте...

Цитата(REZiaMIX)
А зачем посылать 3 инта отдельно?)
А ты уверен, что выравнивание у структуры будет на обеих сторонах (клиент-сервер) одинаковым?  smile 
PM   Вверх
knopka
Дата 20.11.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Большое спасибо to REZiaMIX и bsa очень помогли вопрос закрыт
PM MAIL ICQ   Вверх
REZiaMIX
Дата 20.11.2008, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @ 20.11.2008,  11:54)
ты уверен, что выравнивание у структуры будет на обеих сторонах (клиент-сервер) одинаковым?  smile

Хм , ну если здесь пишем клиент  , то выравнивание задать можем , значит можем быть уверенны)
Вообще , нужно знать что нужно знать протокол клиент<->сервер , чтобы таких вопросов не возникало)
Думаю в данном случае оба решения подойдут)


--------------------
user posted image
PM MAIL   Вверх
knopka
Дата 20.11.2008, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ДА оба подходят
PM MAIL ICQ   Вверх
J0ker
Дата 20.11.2008, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



все вышенаписанное для TCP соединения на прием работать НЕ БУДЕТ
т.к. фрагментация


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 21.11.2008, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @ 20.11.2008,  20:26)
все вышенаписанное для TCP соединения на прием работать НЕ БУДЕТ
т.к. фрагментация

Хм , поясни , у меня все работает как ни крути


--------------------
user posted image
PM MAIL   Вверх
bsa
Дата 21.11.2008, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Кстати, мой вариант работать точно не должен - в описании recv написано, что в случае если полученные данные не помещаются в буфер - излишек теряется. Таким образом действительно надо делать все через вектор...
PM   Вверх
J0ker
Дата 21.11.2008, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(REZiaMIX @ 21.11.2008,  08:25)
Цитата(J0ker @ 20.11.2008,  20:26)
все вышенаписанное для TCP соединения на прием работать НЕ БУДЕТ
т.к. фрагментация

Хм , поясни , у меня все работает как ни крути

ну просто пока везет  smile 
данные, отправленные через TCP могут приходить как угодно фрагментированные, даже если были отправлены через send одним куском
recv заполняет буфер только тем, что пришло на данный момент

Добавлено через 1 минуту и 33 секунды
Цитата(bsa @  21.11.2008,  10:23 Найти цитируемый пост)
Кстати, мой вариант работать точно не должен - в описании recv написано, что в случае если полученные данные не помещаются в буфер - излишек теряется.

это верно только для UDP пакетов
для TCP ничего не теряется

Это сообщение отредактировал(а) J0ker - 21.11.2008, 18:50


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 22.11.2008, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @ 21.11.2008,  18:49)
данные, отправленные через TCP могут приходить как угодно фрагментированные, даже если были отправлены через send одним куском
recv заполняет буфер только тем, что пришло на данный момент

В данном случае просто рассматривается логика протокола(т.е. все в идеальном состоянии) , а фрагментирование это уже другой разговор.


--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 22.11.2008, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(REZiaMIX @ 22.11.2008,  12:26)
Цитата(J0ker @ 21.11.2008,  18:49)
данные, отправленные через TCP могут приходить как угодно фрагментированные, даже если были отправлены через send одним куском
recv заполняет буфер только тем, что пришло на данный момент

В данном случае просто рассматривается логика протокола(т.е. все в идеальном состоянии) , а фрагментирование это уже другой разговор.

фрагментация относится как раз к логике протокола TCP
идеального состояния тут не существует - фрагментация может быть даже на локальной машине


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 23.11.2008, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @ 22.11.2008,  17:26)
фрагментация относится как раз к логике протокола TCP
идеального состояния тут не существует - фрагментация может быть даже на локальной машине

Идеально состояние - нет потери пакетов , отсутствие фрагментации , но тут суть в том. Если вместо вызова recv подставить функцию , обеспечивающую склейку пакетов и тд , то этот подход будет работать как надо в любых предусмотренных случаях
P.S. Сотый пост)

Это сообщение отредактировал(а) REZiaMIX - 23.11.2008, 11:55


--------------------
user posted image
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




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


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

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