Опция с разделителями длины, вероятно, является лучшим выбором.Это позволяет вам быть умным в распределении ваших буферов на принимающей стороне и позволяет отправлять сообщения, содержащие любой символ, который вы хотите.Это также избавляет вас от необходимости внимательно изучать каждый символ, чтобы увидеть, дошли ли вы до конца сообщения.К сожалению, это очень легко реализовать плохо.
Я предоставлю вам хороший код, который сделает это правильно.
На стороне получателя:
unsigned char lenbuf[4];
// This whole thing with the while loop occurs twice here, should probably
// have its own function.
{
bytesRead = 0;
while (bytesRead < 4) {
//read as much as we can. note: byteInc may not == len-bytesRead.
int byteInc = recv(socket, &lenbuf[bytesRead], 4-bytesRead, 0);
if(byteInc != SOCKET_ERROR)
{
bytesRead += byteInc;
}
else
{
//should probably handle this error properly
break;
}
}
} // end scope for bytesRead
unsigned int len = ((lenbuf[0] & 0xffu) << 24) | ((lenbuf[1] & 0xffu) << 16)
| ((lenbuf[2] & 0xffu) << 8) | (lenbuf[3] & 0xffu);
::std::vector<char> buffer;
buffer.resize(len);
{
unsigned int bytesRead = 0;
while(bytesRead < len)
{
//read as much as we can. note: byteInc may not == len-bytesRead.
int byteInc = recv(socket, &buffer[bytesRead], len-bytesRead, 0);
if(byteInc != SOCKET_ERROR)
{
bytesRead += byteInc;
}
else
{
//should probably handle this error properly
break;
}
}
//buffer now contains the complete message.
some_processing_function(buffer);
}
На отправляющей стороне:
const unsigned char lenbuf[4] = {
((bytesToSend >> 24) & 0xffu), ((bytesToSend >> 16) & 0xffu),
((bytesToSend >> 8) & 0xffu), (bytesToSend & 0xffu)
};
// This basic block is repeated twice and should be in a function
{
unsigned int bytesSent = 0;
while (bytesSend < 4) {
const int sentNow = send(socket, &lenbuf[bytesSent], 4-bytesSent, 0);
if (sentNow != SOCKET_ERROR) {
bytesSent += sentNow;
} else {
// Should handle this error somehow.
break;
}
}
}
{
unsigned int bytesSent = 0;
while (bytesSent < bytesToSend) {
const unsigned int toSend = bytesToSend - bytesSent;
const int sentNow = send(socket, &byteBuf[bytesSent], toSend, 0);
if (sentNow != SOCKET_ERROR) {
bytesSent += sentNow;
} else {
// Should handle this error somehow.
break;
}
}
}
Основная проблема, которую имеет другой код, размещенный здесь, заключается в том, что он не очень хорошо обрабатывает вещи, если вы получаете только часть длины, а не всю вещь.Ничто не говорит о том, что информация не будет разделена так, что она будет разбита на середину информации о длине.
Другая проблема заключается в том, что длина отправляется способом, который не является ЦП инезависимость от компилятора.Различные типы процессоров и разные компиляторы C ++ хранят свои целые числа по-разному.Если комбинация компилятор / ЦП, используемая отправителем, отличается от комбинации компилятор / ЦП, используемой получателем, это вызовет проблемы.
Таким образом, явно разбирая целое число на символы нейтральным по платформе способом и помещая егоснова вместе - лучший путь.