2016-07-29 3 views
0

Я отправляю данные (10 файлов, приблизительно 10-20 кб каждый), используя сокеты в C++ в Linux.Проблема сокета в отправке данных

Мой псевдокод на сервере:

for(i=0;i<10;i++){ 
    ret = send(sockfd, filedata, filedatasize, 0); 
} 

ret возвращает правильный размер файла для всех файлов данных, без каких-либо ошибок, но клиент получает только 4-5 файлов.

Но, если я использую вместо этого:

for(i=0;i<10;i++){ 
    ret = send(sockfd, filedata, filedatasize, 0); 
    sleep(1); 
} 

Клиент получает все файлы, а не ошибки!

В чем проблема?

Я пробовал настройку SO_RCVBUF и SO_SNDBUF, но никаких изменений.

EDIT: (полный код имеет 200000 строк, чтобы вставить!)

Вот код сервера:

int Socket::sendMsg(char * data, unsigned int uiSize) 
{ 
    unsigned short * us; 
    int i, iRet; 


     us = (unsigned short *)(m_pSendBuffer); 
     *us = (unsigned short)(uiSize + 2); 

     memcpy((char *)m_pSendBuffer + 2, data, uiSize); 
     iRet = isend(m_pSendBuffer, uiSize + 2); 
     if (iRet<0) { 
      return SOCKET_ERROR; 
     } 
     return iRet; 
} 
int Socket::isend(char * data, int size) 
{ 
    int outlen, ret; 

    outlen= 0; 
    while (outlen< size) { 
     ret= send(sockfd, (data+ outlen), size - outlen, 0); 

     if (ret< 0) { 
      return -1; 
     } 
     else outlen+= ret; 
    } 
    return outlen; 
} 

Вот код клиента:

void XSocket::onRead() 
{ 
    int iRet; 
    unsigned short * usp; 
    unsigned int uiReadSize; 

    while (1) { 
     iRet = recv(m_Sock, (char *)m_pRecvBuffer, 2, 0); 
     uiReadSize = 0; 


     usp = (unsigned short *)(m_pRecvBuffer); 
     uiReadSize = (int)(*usp - 2); 

     iRet = recv(m_Sock, (char *)(m_pRecvBuffer + 2), uiReadSize, 0); 

     if (iRet < 0) { 
      //return error    
     } 
     else if (iRet == 0) { 
      //disconnect 
     } 
     //PROCCESS MSG 
    } 
} 
+0

Можете ли вы показать код на стороне клиента? –

+0

это tcp или udp? –

+0

TCP @SamerTufail – Octavio

ответ

1

На клиенте сторона:

  1. вы не выполняете обработку ошибок при первом вызове recv(), а ваш второй вызов recv() не нарушает цикл, если сервер отключается изящно.

  2. Вы не зацикливаете чтение каждого буфера данных, например, вы выполняете отправку их на стороне сервера. Между количеством отправленных байтов и количеством полученных байтов не существует отношения 1 к 1. Если вы ожидаете прибытия числа X байтов, продолжайте читать, пока вы фактически не получите столько байтов.

Учитывая эти ошибки, нет гарантии, что ваш клиент действительно получает все данные правильно.

Попробуйте что-то больше, как это:

void XSocket::onRead() 
{ 
    int iRet; 
    unsigned short * usp; 
    unsigned int uiReadSize; 

    while (1) { 
     iRet = irecv((char *)m_pRecvBuffer, 2); 
     if (iRet<= 0) { 
      break; 
     } 

     usp = (unsigned short *)(m_pRecvBuffer); 
     uiReadSize = (int)(*usp - 2); 

     iRet = irecv((char *)(m_pRecvBuffer + 2), uiReadSize); 
     if (iRet<= 0) { 
      break; 
     } 

     //PROCCESS MSG 
    } 
} 

int XSocket::irecv(char * data, int size) 
{ 
    int inlen, ret; 

    inlen= 0; 
    while (inlen< size) { 
     ret= recv(m_Sock, (data+ inlen), size - inlen, 0); 

     if (ret< 0) { 
      return -1; 
     } 
     else if (ret== 0) { 
      return 0; 
     } 
     else { 
      inlen+= ret; 
     } 
    } 
    return inlen; 
} 
+0

привет @Remy Lebeau, im закодированный псевдокод, полный источник имеет 200k строк! im рассмотрели 2 случая в полном кодексе. – Octavio

+0

это решение для решения триггера epoll! благодаря! – Octavio

0

им решить эту проблему !!, им изменило Epoll от края триггера для запуска уровня, и решить!

Смежные вопросы