2016-06-30 2 views
-1

Я читаю URL-адрес изображения, отправленный с Java-клиента на сервер C++ из Sockets. Сервер прекращает чтение через RECV(), когда он обнаруживает, есть нулевой символ в полукокса буфере [], как я ниже в следующем коде:Как остановить C++ recv(), когда чтение строки закончено?

void * SocketServer::clientController(void *obj) 
{ 
    // Retrieve client connection information 
    dataSocket *data = (dataSocket*) obj; 

    // Receive data from a client step by step and append data in String message 
    string message; 
    int bytes = 0; 
    do 
    { 
     char buffer[12] = {0}; 
     bytes = recv(data->descriptor, buffer, 12, 0); 

     if (bytes > 0) // Build message 
     { 
      message.append(buffer, bytes); 
      cout << "Message: " << message << endl; 
     } 
     else // Error when receiving it 
      cout << "Error receiving image URL" << endl; 


     // Check if we are finished reading the image link 
     unsigned int i = 0; 
     bool finished = false; 
     while (i < sizeof(buffer)/sizeof(buffer[0]) && !finished) 
     { 
      finished = buffer[i] == '\0'; 
      i++; 
     } 

     if (finished) 
      break; 

    } 
    while (bytes > 0); 

    cout << message << endl; 

    close(data->descriptor); 
    pthread_exit(NULL); 
} 

есть лучший и более элегантный способ сделать это?

Я прочитал про отправку первого размера URL-адреса, но я точно не знаю, как остановить recv() с ним. Я думаю, это делается путем подсчета полученных байтов, пока не будет достигнут размер URL-адреса. В этот момент мы должны закончить чтение.

Другим подходом может быть закрытие сокета Java, так что recv() вернет -1, и цикл будет завершен. Однако, учитывая, что мой Java-клиент ждет ответа с сервера C++, закрытие сокета, а затем его повторное открытие, не представляется подходящим вариантом.

Спасибо, Гектор

ответ

0

Кроме того ваш буфер имеет необычный размер (один, как правило, выбирает силу 2, так что 8, 16, 32, ...), и это выглядит немного мал для вашего намерение, ваш подход кажется мне прекрасным:

Я предполагаю, что ваш клиент java отправит нулевую завершенную строку, а затем все равно ждет, i. е. в частности, он не отправляет никаких дополнительных данных. Поэтому после того, как вы получили символ 0, больше не будет никаких данных, чтобы получать больше, поэтому нет необходимости беспокоиться о чем-то явно, что recv делает неявно (recv обычно возвращает только доступные данные, даже если он меньше, чем буфер может потреблять).

Помните, что вы инициализировали буфер с 0, поэтому, если вы проверили весь буфер (вместо диапазона [buffer, buffer + bytes), вы можете обнаружить ложный положительный результат (если вы получили менее 12 символов на первой итерации)! Однако обнаружение символа 0 может быть выполнено более элегантно, хотя в любом случае:

if(std::find(buffer, buffer + bytes, 0) < buffer + bytes) 
{ 
    // found the 0 character! 
    break; 
}