В настоящее время я работаю над небольшим проектом: есть протокол для отправки некоторых строк через UDP, реализованный со стандартным интерфейсом C.
Хотя он работает довольно хорошо, я хотел бы переписать его еще с некоторымисложный C ++ (рассмотрим это упражнение).
В настоящее время это что-то вроде этого: Клиент хочет эту строку, поэтому он отправляет следующее struct
:
struct request {
uint8_t msg_type;// == 1
uint64_t key; // generated randomly to identify each request
}
В новой реализации я хочуиспользуйте boost::asio
, поэтому на сервере у меня есть следующий фрагмент кода:
boost::asio::io_service io_service;
boost::asio::ip::udp::endpoint client_endpoint;
boost::asio::ip::udp::socket socket(io_service,
boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(),
m_serverPort));
boost::asio::streambuf sb;
boost::asio::streambuf::mutable_buffers_type mutableBuf =
sb.prepare(sizeof(request));
size_t received_bytes = socket.receive_from(mutableBuf, client_endpoint);
sb.commit(received_bytes);
request r;
std::istream is(&sb);
is >> msg_type;
is >> key;
key = __bswap64(key); // I'm using network byteorder for numbers sent with this protocol
// and there's no ntohll function on Snow Leopard (at least I can't
// find one)
sb.consume(received_bytes);
И вот моя проблема: значение «ключа», которое я пытаюсь получить таким образом, неверно - я имею в виду, что я получаю что-то, чтоЯ не отправлял.
Вот мои подозрения:
- __ bswap64 не конвертирует сеть в хост (little-endian) byteorder
- Я неправильно понял, как использовать boost:: asio :: streambuf с потоками
- Существует некоторая несовместимость между старым интерфейсом C и boost (но я так не думаю, потому что я обнаружил, что функции boost просто обертки для него)
РЕДАКТИРОВАТЬ: хм они говорят "не хвалите брод, пока вы не закончите".Теперь у меня очень похожая проблема в другом месте моего кода.У меня есть следующая структура, которая отправляется в качестве ответа на вышеупомянутый запрос:
struct __attribute__ ((packed)) CITE_MSG_T
{
uint8_t msg_id;
uint64_t key; // must be the same as in request
uint16_t index; // part number
uint16_t parts; // number of all parts
CITE_PART_T text; // message being sent
};
//where CITE_PART_T is:
struct __attribute__ ((packed)) CITE_PART_T
{
uint16_t data_length;
char* data;
};
и следующий фрагмент кода: http://pastebin.com/eTzq6AWQ. К сожалению, есть еще одна ошибка, и я снова читаю то, что у меня естьне отправлено - replyMsg.parts и replyMsg.index всегда равны 0, хотя старая реализация говорит, что они, например, 3 и 10. Что не так в этот раз?Как вы можете видеть, я забочусь о заполнении и использую read вместо operator >>.Если вы удивляетесь, почему я читаю эту структуру поле за полем, вот ответ: сервер отправляет две разные структуры, обе начинаются с msg_id, одна в случае успеха и другая в случае сбоя.Прямо сейчас я просто не знаю, как это сделать иначе.