Проблема при передачи большого куска данных по TCP
От: LeXa-XL  
Дата: 19.12.06 12:48
Оценка:
Проблема в следующем, есть структура данных:

#define MAXPOINTS 2000

typedef struct {

char id1;
char id2;
short status;
char data1;
char data2;
float summ;
double time;
unsigned int counter;

short graph1[MAXPOINTS];
float graph2[MAXPOINTS];

} packet_t;


если MAXPOINTS порядка 1000 — то все отысылается и принимается замечательно, если — >1500, в частности =2000 и выше — приходять битые данные, точнее graph1 и graph2 вроде нормальные, остальные — мусор. Грешил на выравнивание, менял тип данных — проблема осталась.


Буду рад любым предложениям по сабжу.
Re: Проблема при передачи большого куска данных по TCP
От: TarasCo  
Дата: 19.12.06 13:03
Оценка:
LX>если MAXPOINTS порядка 1000 — то все отысылается и принимается замечательно, если — >1500, в частности =2000 и выше — приходять битые данные, точнее graph1 и graph2 вроде нормальные, остальные — мусор. Грешил на выравнивание, менял тип данных — проблема осталась.

Выравнивание конечно нужно чтобы было одинковым

LX>Буду рад любым предложениям по сабжу.


У Вас, возможно, сокет на передающей стороне работает в неблокирующем режиме а send не контролируется на возможные ошибки ( переполнение буфера ), в результате данные просто не все передаются. Также возможно буфера освобождаются раньше, чем закончена передача. Не было каких нибудь непонятных падений?
Да пребудет с тобою сила
Re[2]: Проблема при передачи большого куска данных по TCP
От: LeXa-XL  
Дата: 19.12.06 13:11
Оценка:
Здравствуйте, TarasCo, Вы писали:

LX>>если MAXPOINTS порядка 1000 — то все отысылается и принимается замечательно, если — >1500, в частности =2000 и выше — приходять битые данные, точнее graph1 и graph2 вроде нормальные, остальные — мусор. Грешил на выравнивание, менял тип данных — проблема осталась.


TC>Выравнивание конечно нужно чтобы было одинковым

Это да, согласен, но если архитектура одна — то система сама заботится об этом, поросто размер пакета немного распухает... нет дело в другом... ведь при передачи 1000 елементов — все работает.

LX>>Буду рад любым предложениям по сабжу.


TC>У Вас, возможно, сокет на передающей стороне работает в неблокирующем режиме а send не контролируется на возможные ошибки ( переполнение буфера ), в результате данные просто не все передаются. Также возможно буфера освобождаются раньше, чем закончена передача. Не было каких нибудь непонятных падений?


пробовал и блокирующий и неблокирующие режим с проверкой аля

if( errno!=EINTR && errno!=EAGAIN && errno!=EWOULDBLOCK )
return -1; // owerwise — return error
else
continue; // interrupted? — restart the read

Контрольные суммы пакетов совпадаю как при отправке так и при приеме, срого контолируется число отправленных и принятых байт, вот исходники функций

// sendn - send n bytes into socket
//         s - socket descriptor
//         bp - data buffer
//         n - number of bytes to send    
int sendn(SOCKET s, char *bp, size_t n) {
    size_t        cnt;
    ssize_t        rc;
    const char    *ptr;
    ptr = bp;
    cnt = n;
    while(cnt > 0) {
        rc = send(s, ptr, cnt, 0);
    if( rc <= 0) {
            if(errno != EINTR && errno!=EAGAIN && errno!=EWOULDBLOCK )
                return(-1);            // return error
            else
              rc = 0;              //restart writing, calling again
        }
        cnt -= rc;
        ptr += rc;
    }
    return n;
} 


// resvn - receive n bytes from socket
//         s - socket descriptor
//         bp - data buffer
//         n - number of bytes to recv 
int recvn(SOCKET s, char *bp, size_t n) {
  size_t cnt;
  ssize_t rc;
  const char *ptr;
  ptr = bp;
  cnt = n;
  while( cnt > 0 ) {
    rc = recv( s, bp, cnt, 0 );
    if( rc < 0 ) {       // error?
      if( errno!=EINTR && errno!=EAGAIN && errno!=EWOULDBLOCK )
        return -1;       // owerwise - return error
      else
        continue;        // interrupted? - restart the read
        
    }
    if( rc == 0 )        // EOF?
      return n - cnt;    // return short count
    cnt -= rc;
    ptr += rc;
  }
  return n;
}
Re[3]: Проблема при передачи большого куска данных по TCP
От: Аноним  
Дата: 19.12.06 16:12
Оценка:
LX>Контрольные суммы пакетов совпадаю как при отправке так и при приеме, срого контолируется число отправленных и принятых байт, вот исходники функций

как-то это не вяжется с тем, что приходит мусор.
Может ф-я подсчёта контрольной суммы портит данные?
Re[3]: Проблема при передачи большого куска данных по TCP
От: Аноним  
Дата: 19.12.06 19:49
Оценка:
LX>// resvn — receive n bytes from socket
LX>// s — socket descriptor
LX>// bp — data buffer
LX>// n — number of bytes to recv
LX>int recvn(SOCKET s, char *bp, size_t n) {
LX> size_t cnt;
LX> ssize_t rc;
LX> const char *ptr;
LX> ptr = bp;
LX> cnt = n;
LX> while( cnt > 0 ) {
LX> rc = recv( s, bp, cnt, 0 ); //[b]А может rc = recv( s, ptr, cnt, 0 );[/bi]
LX> if( rc < 0 ) { // error?
LX> if( errno!=EINTR && errno!=EAGAIN && errno!=EWOULDBLOCK )
LX> return -1; // owerwise — return error
LX> else
LX> continue; // interrupted? — restart the read

LX> }

LX> if( rc == 0 ) // EOF?
LX> return n — cnt; // return short count
LX> cnt -= rc;
LX> ptr += rc;
LX> }
LX> return n;
LX>}


LX>[/ccode]
Re[4]: Проблема при передачи большого куска данных по TCP
От: Аноним  
Дата: 19.12.06 22:05
Оценка:
Здравствуйте, Аноним, Вы писали:

LX>>// resvn — receive n bytes from socket

LX>>// s — socket descriptor
LX>>// bp — data buffer
LX>>// n — number of bytes to recv
LX>>int recvn(SOCKET s, char *bp, size_t n) {
LX>> size_t cnt;
LX>> ssize_t rc;
LX>> const char *ptr;
LX>> ptr = bp;
LX>> cnt = n;
LX>> while( cnt > 0 ) {
LX>> rc = recv( s, bp, cnt, 0 ); //[b]А может rc = recv( s, ptr, cnt, 0 );[/bi]
LX>> if( rc < 0 ) { // error?
LX>> if( errno!=EINTR && errno!=EAGAIN && errno!=EWOULDBLOCK )
LX>> return -1; // owerwise — return error
LX>> else
LX>> continue; // interrupted? — restart the read

LX>> }

LX>> if( rc == 0 ) // EOF?
LX>> return n — cnt; // return short count
LX>> cnt -= rc;
LX>> ptr += rc;
LX>> }
LX>> return n;
LX>>}


LX>>[/ccode]



сенкс, проверю....
Re[4]: Проблема при передачи большого куска данных по TCP
От: Michael Chelnokov Украина  
Дата: 20.12.06 14:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Может ф-я подсчёта контрольной суммы портит данные?


Ага, однозначно кто-то портит данные уже после приема.
В приведенном коде с send/recv ошибок не вижу.
Re: Проблема при передачи большого куска данных по TCP
От: Michael Chelnokov Украина  
Дата: 20.12.06 14:40
Оценка:
Здравствуйте, LeXa-XL, Вы писали:

LX>если MAXPOINTS порядка 1000 — то все отысылается и принимается замечательно, если — >1500, в частности =2000 и выше — приходять битые данные, точнее graph1 и graph2 вроде нормальные, остальные — мусор.


Очень похоже на то что ты где-то успеваешь сделать free (delete) принятой структуре. Потом вызываешь malloc (new), оно тебе возвращает тот же указатель и ты туда что-то пишешь. Потому начало структуры и получается запорченным — указатель на собственно принятую структуру уже давно недействителен, а память уже используется под другие данные.
Либо еще вариант. Недавно видел его в одном из около-апачевских модулей (они уже исправили):

somestruct_t* p=(somestruct_t*)malloc(sizeof(somestruct_t*));

вместо

somestruct_t* p=(somestruct_t*)malloc(sizeof(somestruct_t));

Со всеми вытекающими последствиями...
Re[4]: Проблема при передачи большого куска данных по TCP
От: LeXa-XL  
Дата: 26.12.06 12:40
Оценка:
Действительно трабл был именно здесь:


  ....
  const char *ptr;
  ptr = bp;
  cnt = n;
  while( cnt > 0 ) {
    rc = recv( s, bp, cnt, 0 );
    ....
  }
  ....


нужно


  char *ptr;
  ptr = bp;
  cnt = n;
  while( cnt > 0 ) {
    rc = recv( s, ptr, cnt, 0 );


Спасибо всем за содействие, тема закрыта.
Re: Тема закрыта
От: LeXa-XL  
Дата: 26.12.06 12:42
Оценка:
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.