2011-06-14 3 views
2

현재 작은 프로젝트에서 작업 중입니다. 표준 C 인터페이스로 구현 된 UDP를 통해 일부 문자열을 보내는 프로토콜이 있습니다.boost :: asio와 표준 C 소켓 인터페이스 사이의 협력

꽤 잘 작동하지만 좀 더 정교한 C++로 다시 작성하고 싶습니다 (운동으로 생각하십시오).

은 현재이 같은 뭔가 : 그것은이 struct 다음 전송하므로 클라이언트는 해당 문자열을 원하는 : 새로운 구현에서

struct request { 
    uint8_t msg_type;// == 1 
    uint64_t key; // generated randomly to identify each request 
} 

, 내가 서버에 너무 boost::asio를 사용하려면 I 코드의 다음 조각이 :

나는이 방법을 받게하려고 "키"값이 잘못 - 난 내가 보내지 않은 무언가를 얻을 의미 :
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); 

그리고 여기 내 문제입니다. 여기

내 의심과 같습니다

  1. __bswap64는
  2. 내가
  3. 몇 가지있다 스트림을 부스트 :: ASIO :: streambuf의 사용 방법을 잘못 이해 바이트 순서 (리틀 엔디안)를 호스팅하는 네트워크를 변환하지 않습니다 오래된 C 인터페이스와 부스트 사이의 비 호환성 (그러나 나는 그렇게 생각하지 않는다. 부스트 기능은 단지 래퍼가된다.)

편집 : 흠. 그들은 "네가 끝날 때까지 ford를 칭찬하지 마라."라고 말한다. 이제 다른 코드에서 비슷한 문제가 발생했습니다.

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 나는 위의 metioned 요청에 대한 응답으로 전송되는 다음과 같은 구조체가 있습니다. 불행히도 거기에 또 다른 버그가 있고 내가 보낸 적이없는 것을 읽었습니다 - replyMsg.parts와 replyMsg.index는 예전의 구현에서 3과 10이라고되어 ​​있지만 항상 0입니다. 이번에는 무엇이 잘못 되었습니까? 보시다시피 저는 패딩을 처리하고 연산자 >> 대신 읽기를 사용합니다. 왜 구조 필드를 필드별로 읽었는지 궁금하다면 대답은 다음과 같습니다. 서버는 msg_id로 시작하는 두 가지 구조와 실패한 경우 두 가지 구조를 전달합니다. 지금 당장은 다른 방법으로는 모를 것입니다.

답변

3

서식있는 입력을 사용하고 있습니다. 즉, 데이터가 텍스트 인 것처럼 입력해야합니다. un 형식화 된 입력이 필요합니다. operator>> 대신에 사용해야하는 것이므로 std::istream::read 회원 기능에 대해 읽어보십시오.

각 추출 후에 스트림 상태를 확인한 경우 항상 비어있는 코드로 표시되어야하므로 즉시 분명하게 알 수 있습니다.

0

당신은 패딩을 잊어 버렸습니다.

struct request { 
    uint8_t msg_type; 
    char __pad__[3]; // or 7 on 64-bit machine. 
    uint64_t key; 
}; 

당신은 그 문제를 해결 GCC에서 말할 수있는, 속성 (the GCC manual 참조) :

요청 구조는 아마와 같이 제 1 및 제 2 부재 사이에 컴파일러에 의해 삽입 된 적어도 3 바이트를 가지고
struct __attribute__ ((__packed__)) request { ... 

네, 저는 바이너리 대신 텍스트를 읽으 려한다는 사실을 놓쳤습니다. 먼저 수정, 나중에 맞추기/패딩으로 물리 칠 수 있습니다.

+0

확인 - 실제로 실제로 문제가 해결되었지만 코드의 어딘가에 있기 때문에 실제 선언을 검색하는 것보다 기억 한대로 작성하는 것이 더 빠릅니다. 진짜 문제는 내가 읽지 않고 연산자 >>를 사용했다는 것입니다. 어쨌든 도움을 주셔서 감사합니다! –

관련 문제