|
이 문제는 TCP의 특성 때문에 생기는 문제입니다. 블럭킹/넌블럭킹과는 상관없고요.
TCP가 스트림 기반이기 때문에, 데이터가 전송측에서 보낸 만큼 오는게 아니라 네트워크 상황에 따라서
네트워크 장치에 수신된 만큼만 리턴을 해주게 됩니다.
예를 들어서, 송신측에서, 100 바이트, 100 바이트, 100 바이트, 이렇게 3번을 보냈다면
수신측에서는 한꺼번에 300 바이트를 읽는 경우도 있으며, 150씩 2번에 나뉘어져 받을 수도 있습니다.
네트워크가 무진장 느리다면 30바이트, 20바이트, 50바이트, 이런식으로 잘게 나뉘어져 오는 경우도 있어요.
그러니까 처리할 때 nRcvLen 만큼 한꺼번에 읽어들이면 안 되고,
처리에 필요한 만큼 수신 되었는지 수신 크기를 확인하고 ReceiveBuf 에 사용할 만큼만 수신해서
나머지는 그냥 네트워크 버퍼에 남겨두어야 합니다.
그럼 좋은 프로그램 만드세요~
lucyfer 님이 쓰신 글 :
: TServerSocket을 사용하고 있구요.
:
: ClientRead 이벤트에서 다음과 같이 처리를 하고 있습니다.
:
: int nRcvLen = Socket->ReceiveLength();
: if(nRcvLen > 0)
: {
: JOB_PACKET Job_Msg = {0,};
: char Buffer[2048] = {0,};
:
: Socket->ReceiveBuf(Buffer, nRcvLen);
: memcpy(&Job_Msg, Buffer, sizeof(JOB_PACKET));
:
: if(Job_Msg.Magic == 'TEST')
: {
: String Test1= (String)Job_Msg.test1;
: String Test2= (String)Job_Msg.test2;
: String Test3= (String)Job_Msg.test3;
: String Test4= (String)Job_Msg.test4;
:
: Memo1->Lines->Add(Test1 + Test2 + Test3 + Test4);
: }
: }
:
: 클라이언트에서 SendBuf 로 보내게 되는데. 이때 버튼 다운이벤트에 1개씩 보내거나,
: 보내고 슬립을 주고 다음 보내고 하는 건 문제 없이 잘 통신이 됩니다.
:
: 그러나, SendBuf 후 바로 SendBuf를 보내게 되면 다음에 보내게 된것은 받아서 처리를 못하며,
: 이렇게 연속으로 보내게 되면 서버가 종료되는 문제가 발생합니다.
: 에러가 발생하는 부분은 memcpy(&Job_Msg, Buffer, sizeof(JOB_PACKET)); 부분으로
: 작업중인 메모리를 복사하는 것때문에 그렇지 않을까 생각을 하는데.
: 이부분을 어떻게 수정을 해야 좋을지 지혜를 구해봅니다.
:
: 감사합니다.
|