Я пытаюсь реализовать протокол (T) LV через TCP, отправляя буферы протокола от клиента Python и получая его с сервера C ++.
Мой код выглядит примерно так:
char* buffer[RCVBUFSIZE];
int recvsize= 0;
// Filling my buffer with as much as possible.
while(true) {
if(recvsize == RCVBUFSIZE) {
break;
} else if(recvsize+= recv(sock, buffer+recvsize, sizeof(buffer)-recvsize, 0) < 1) {
break;
}
}
//Parsing LV protocol
while(true) {
unsigned short protosize= 0;
//Copy first two bytes into protosize
memcpy((char *) &protosize, buffer, sizeof(unsigned short));
if(protosize == 0) { break; } // Protocol indicates EOM be setting length to "0"
void* protomsg[protosize];
memcpy(protomsg, buffer+sizeof(unsigned short), protosize);
int msglength= sizeof(unsigned short)+protosize;
//Now I'll move the whole buffer to the left so that I don't have to keep track of where I'm at.
memmove(buffer, buffer+msglength, RCVBUFSIZE-msglength);
protoMsg pm;
if(!pm.ParseFromArray(protomsg, protosize)) { break; } // Parsing failed.
// Do stuff with parsed message.
}
Теперь у меня есть несколько проблем:
- Цикл while, получающий сообщение, никогда не прекращается.Я подозреваю, что вызов recv блокируется, когда больше не осталось никаких данных, в то время как я ожидал, что они вернутся с ошибкой.Я нашел функцию выбора, чтобы проверить, есть ли что прочитать.Я попробую.Но когда я вызываю функцию receive только один раз, чтобы пропустить эту проблему (полученное сообщение имеет размер ~ 10 байт, поэтому я ожидаю, что все будет собрано за один вызов.) У меня возникает другая проблема:
- memcpy и memmove don 'Кажется, что работает как ожидалось.В первом цикле короткое замыкание обрабатывается, как и ожидалось (я получаю то же значение, которое отправляю на другой стороне), но затем все из анализа буфера протокола завершается неудачно.Я что-то не так понял?
Редактировать: Что касается комментария о ntohs - я передаю short как little-endian в настоящее время, забыл упомянуть об этом.(Я изменит это все еще, кстати.)
Третье редактирование: Код теперь работает, но мне пришлось изменить следующее:
char* buffer[RCVBUFSIZE];
int recvsize= 0;
// Filling my buffer with as much as possible.
while(true) {
if(recvsize == RCVBUFSIZE) {
break;
} else if((recvsize+= recv(sock, buffer+recvsize, sizeof(buffer)-recvsize, 0)) < 1) {
break;
} else if(recvsize > 1) {
unsigned short msglength= 0;
memcpy((char *) &msglength, buffer+recvsize-sizeof(unsigned short), sizeof(unsigned short));
if(msglength == 0) { break; } // Received a full transmission.
}
}
Итак, сначала яМне нужно было добавить квадратные скобки вокруг оператора recvsize+= recv()
, а во-вторых, поскольку неблокирующий метод не работал по какой-то причине, я сейчас проверяю, переводятся ли последние два переданных байта в 0 при чтении короткого знака без знака.Это, вероятно, приводит к проблеме, если я случайно прочитал 0, а не поле длины.Я начну еще один вопрос по этому поводу, вероятно.
Я также изменил protomsg
на char[]
, но я не думаю, что это действительно что-то изменило.(У меня уже был разбор, работающий с массивом void ..)