2016-07-01 2 views
0

나는 임의의 클라이언트 (socket.recv() 사용)로부터 tcp 메시지를 수신하는 작업의 일부인 C# 시스템을 유지 관리하고 있습니다. 우리는 메시지 프로토콜을 가지고 있기 때문에 외부 개발자들이 형식이 잘 짜여진 메시지를 채울 수 있습니다.어떻게 메시지를받을 수 있습니까?

메시지 형식은 다음과 같이

{ public data(fixed length):private data(variable length) } 

메시지를 수신하려면, 우리는이 메시지에 개인 데이터 길이 필드가 필요하지만, 누군가가 잘못 길이 number.How를 입력 할 수 있습니다 메시지를 보낼 필요 이 수요를 충족시킬 수 있습니까? 적어도 안정적으로, 당신은 잘못된 형식의 메시지를 수용 할 수

public static int ReceiveMessage(int totalByteNumber, Socket socket, byte[] recvBuffer) 
{ 
    try 
    { 
    int offset = 0; 
    do 
    { 
     try 
     { 
     int num = socket.Receive(recvBuffer, offset, totalByteNumber - offset, SocketFlags.None); 
     if (num == 0) 
     { 
      throw new ApplicationException(); 
     } 
     offset += num; 
     } 
     catch (SocketException ex) 
     { 
     if (ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) 
      Thread.Sleep(30); 
     else if (ex.SocketErrorCode == SocketError.WouldBlock) 
     { 
      socket.Blocking = true; 
      Thread.Sleep(30); 
     } 
     else 
     { 
      LogManager.WriteError("Origin IP:" + (object) ((IPEndPoint) socket.RemoteEndPoint).Address); 
      throw ex; 
     } 
     } 
    } 
    while (offset < totalByteNumber); 
    return offset; 
    } 
    finally 
    { 
    SocketUtility.LogMessage("Recv", recvBuffer, socket); 
    } 
} 
+0

단순히 전체 메시지 반환 오류를 읽을 수없는 경우. 메시지는 형식화되고 채워 져야합니다. – BWA

+0

당신 말이 맞아요.하지만 그건 회사 정치에 관한 것입니다. 그래서 기술적으로 말하면, 거기에 대한 해결책이 있습니까? –

+0

포트에서 주어진 바이트를 읽을 수 있습니다. 구문 분석 msg를 시도하고 너무 짧으면 더 읽은 후 prev 읽기와 병합하고 끝 메시지를 찾으십시오. – BWA

답변

0

:

여기 내 코드입니다. TCP는 메시지 경계를 유지하지 않으므로 메시지를 보낸 기간을 알 수 없습니다.

일반적으로 간단한 요청이 있고 요청자가 하나의 send 시스템 호출에서 전체 요청을 보내는 경우 각 수신은 정확하게 하나의 요청 메시지를 반환하지만 신뢰할 수는 없습니다. 예를 들어 요청자가 두 개의 연속을 보냈을 경우 단일 수신 호출에서 둘 다 반환 될 수 있도록 프로세스가 예약되기 전에 요청자가 합쳐질 수 있습니다.

귀하의 옵션 :

  • 메시지 (널 바이트, 또는 빈 줄에
  • 일부 플래그 패턴 (대부분의 바이너리 프로토콜이 방식으로 작동) 기대 얼마나을 알리는 메시지의 길이 필드 텍스트 또는 무엇이든간에, HTTP와 같은 텍스트 기반 프로토콜은 이런 식으로 작동합니다.)
  • 파일 끝 (예 : 호출자가 요청을 보내고 socket.Shutdown(Send);을 호출하면 EOF를 얻고 그 결과가 모두 예상된다는 것을 알 수 있습니다. 원샷 협상)
+0

. 매우 도움이됩니다. –

관련 문제