2014-11-01 5 views
2

내 프로그램을 사용하여 서버와 클라이언트 컴퓨터간에 데이터 통신을 시도하고 있습니다. 나는 TCP에 대한 지식이 거의 없으며 그것이 어떻게 작동 하는지를 알기 때문에 나는 정말로 도움이 필요하다. 이 버퍼에 연재됩니다클라이언트 서버 메시지 해석

int _header_signature; 
int _offset_a; 
int _offset_b; 
int _size_a; 
int _size_b; 
wchar_t stuff[_size_a]; 
wchar_t stuff2[_size_b]; 
int _footer_signature; 

및 윈속의 send() 방법을 사용하여 보내 가져옵니다 다음과 같이

는 지금까지 내 자신의 간단한 프로토콜의 메시지가 정의된다.

제 목표는 어떻게 든이 메시지를 해석하고 서버 컴퓨터의 유사한 구조체에서 데이터를 추출하는 것입니다. 이것은 클라이언트와 서버 간의 일대일 연결입니다.

이 데이터를 서버 부분에서 어떻게 해석하겠습니까?

겠습니까 I : 내가 버퍼에받을 것을 쓰고, 메시지 해석 작업을 시작 recv()를 호출

A) 루프recv()는 반환 할 아무것도가 없으며 보낸 메시지 모두에 지금 경우에만 버퍼? 클라이언트가 메시지를 계속 보내면 어떤 일이 일어날 지 잘 모르겠습니다. 두 번째 메시지는 첫 번째 메시지가 recv() 'd 일 때만 도착할 것입니까? 아니면 클라이언트가 메시지를 계속 보내는 한 recv() 계속 물건을 반환 할 것인가?

또는

B)가 메시지의 일부가 도착했습니다 경우에도 와서 빨리이 메시지를 해석하는 작업을 시작? 헤더는 내가 얼마나 더 기대해야하는지 알려줘야한다. (이 작업은 매우 길고 지루한 작업 임)

전체 메시지가 버퍼에 수신되도록하는 방법이 없으며 데이터로 작업 할 수 있도록 구조체에 캐스트해야합니다. 나는 사람을 혼동하는 경우 뭔가 말해 내가 질문 하나에 번들로 꽤 많은 질문이

답변

2

를 업데이트하시기 바랍니다 불분명 경우

나는, 미안 해요.

당신에게 가장 중요한 대답은 TCP 소켓에서 수신을 호출 할 때 메시지을 마술처럼 처리하지 않는다는 것입니다. 사실 그것에 대해 생각해 보면 보장되는 유일한 것은 8 비트 경계에서 데이터를 수신한다는 것입니다. receive 호출은 적어도 하나 이상의 바이트가 가능할 때까지 (아마도 더 많은 바이트) 블럭 될 것이고, 소켓이 닫혀 있다면 빈 버퍼를 리턴 할 것이다.

지식으로 무장하면 질문 2 번에 응답해야합니다 : "전체 메시지가 수신 될 때까지 기다리 나 수신을 계속 유지합니까?"대답은 연달아 전화를 받아야한다는 것입니다 . 입력 버퍼를 파싱하면 응용 프로그램 프로토콜이 지시하는 데이터로 개별 바이트를 deserialize합니다.

실현해야 할 중요한 점 중 하나는 매우 큰 읽기 버퍼를 사용한다고해서 한 번의 호출로 전체 메시지를 수신 할 수 없다는 것입니다. 이것은 이해하는 것이 중요합니다. 즉, 한 번에 1 바이트 정도의 데이터를 수신 할 수 있고 읽기 버퍼의 크기만큼 데이터를받을 수 있다는 가정하에 코드가 작동해야합니다.따라서 읽기 버퍼의 크기를 결정할 때는 네트워크의 MTU에 따라 적절한 값을 선택해야합니다 (1500 바이트와 같은 것이 일반적으로 좋은 선택입니다). recv()을 호출 할 때마다 정확히 읽은 바이트 수를 알 수 있습니다.

일단 데이터 수신을 시작하면 임시 버퍼에 데이터를 복사하고 한 메시지의 헤더를 구문 분석 할만큼 충분한 양이 있으면이를 디코딩하여 전체 메시지를 받았는지 또는 더 보류 중인지 확인하십시오. 전체 메시지를 받으면 응용 프로그램으로 전달하십시오. 이 모든 것은 애플리케이션 과는 독립적으로 작동해야합니다 (수신 코드는 가능한 한 빨리 데이터를 받아 들여 버퍼링하고 파싱 한 다음 디코딩 된 메시지를 애플리케이션에 공급할 수 있어야합니다).

+0

그래서 내게 말하고있는 것은 (recv()가 작성한 버퍼가 내 메시지보다 작다고 가정 할 때) recv()를 호출해야만 메시지의 일부분 만 가져올 수 있습니다. recv()를 호출하면 메시지의 또 다른 작은 부분을 얻고 수신 된만큼 해석합니다. –

+0

예, 실제로 얼마나 큰 버퍼를 사용하는지는 중요하지 않습니다. recv()에 대한 하나의 호출에서 채워지지 않을 수도 있습니다. –

관련 문제