2015-01-08 3 views
0

TCP 클라이언트에 대한 코드를 상속 받았습니다. 메시지를 보낸 다음 완료되면 확인 메시지를 기다립니다. 현재는 메시지를 보내지 만 응답 메시지를 기다리면 수신하지 못합니다. SendMessage() 메서드는 외부 적으로 호출되는 메서드입니다.C# TCP 클라이언트가 메시지를 보내지 만 수신하지 않습니다.

나는 중단 점을 설정하고이 Receive() 방법 안타 볼 수 있지만 결코 ReceiveCallback()

어떤 도움이나 감사 올바른 방향으로 조금씩 이동.

public class SocketService 
{ 
    private ManualResetEvent connectDone = new ManualResetEvent(false); 
    private ManualResetEvent sendDone = new ManualResetEvent(false); 
    private ManualResetEvent receiveDone = new ManualResetEvent(false); 

    string ipAddress; 
    private int portNum; 
    string returnMessage; 
    // private string hostName = Dns.GetHostName(); 

    public SocketService(string ipAddress, int portNum) 
    { 
     this.ipAddress = ipAddress; 
     this.portNum = portNum; 
    } 

    public event Logging OnLogging; 

    private void WriteLogMessage(string message) 
    { 
     if (this.OnLogging != null) 
      this.OnLogging(message); 
    } 

    //char endOfLineSeparator = (char) 0x1C; 
    //char cr = (char) 0x0D; 
    //char vt = (char) 0x0B; 

    public string SendMessage(string message) 
    { 
     IPAddress ip = IPAddress.Parse(this.ipAddress); 
     IPEndPoint remoteEP = new IPEndPoint(ip, portNum); 

     connectDone.Reset(); 

     Socket client = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, 
            ProtocolType.Tcp); 

     client.BeginConnect(remoteEP, 
          new AsyncCallback(ConnectCallback), 
          client); 

     connectDone.WaitOne(); 

     //sendDone.Reset(); 

     WriteLogMessage("send message"); 

     Send(client, message); 
     sendDone.WaitOne(); 

     //receiveDone.Reset(); 

     WriteLogMessage("receive message"); 

     Receive(client); 
     receiveDone.WaitOne(); 

     client.Shutdown(SocketShutdown.Both); 
     client.Close(); 

     return this.returnMessage; 
    } 

    private void Send(Socket client, String data) 
    { 
     byte[] byteData = Encoding.ASCII.GetBytes(data); 

     client.BeginSend(byteData, 
         0, 
         byteData.Length, 
         0, 
         new AsyncCallback(SendCallback), 
         client); 
    } 

    private void SendCallback(IAsyncResult ar) 
    { 
     Socket client = (Socket)ar.AsyncState; 

     int bytesSent = client.EndSend(ar); 

     sendDone.Set(); 
    } 

    private void ConnectCallback(IAsyncResult ar) 
    { 
     Socket client = (Socket)ar.AsyncState; 

     client.EndConnect(ar); 

     connectDone.Set(); 
    } 

    private void Receive(Socket client) 
    { 
     StateObject state = new StateObject(client); 

     client.BeginReceive(state.Buffer, 
          0, 
          StateObject.BufferSize, 
          0, 
          new AsyncCallback(ReceiveCallback), 
          state); 
    } 

    private void ReceiveCallback(IAsyncResult ar) 
    { 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket client = state.WorkSocket; 

     int bytesRead = client.EndReceive(ar); 

     if (bytesRead > 0) 
     { 
      state.StoredContent.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead)); 

      client.BeginReceive(state.Buffer, 
           0, 
           StateObject.BufferSize, 
           0, 
           new AsyncCallback(ReceiveCallback), 
           state); 

      WriteLogMessage(state.StoredContent.ToString()); 
     } 
     else 
     { 
      this.returnMessage = state.StoredContent.ToString(); 

      receiveDone.Set(); 
     } 
    } 
} 
+0

'ManualResetEvent'를 모두 주석 처리하고 다시 시도하십시오.'ReceiveCallback'이 호출됩니까? –

+0

TCP 위에 구현하는 프로토콜에 따라 "메시지"의 정의는 무엇입니까? 상대방은 응답 할 수 있도록 전체 메시지를 받았음을 어떻게 알 수 있습니까? –

+0

BTW : 콜백 동기화가 쉬운 작업이 아니므로 SendTaskAsync, ReceiveTaskAsync 등과 같은 * awaitable * async * 메소드를 사용하는 것이 좋습니다. –

답변

0

결국 아무도 알 수 없었던 것입니다. 이것들은 HL7 메시지 였고, 누락 된 메시지 끝에 숨겨진 문자가 누락되었습니다. 수신자가 메시지의 전송을 기다리는 중 이었지만이 문자가 없으면 완전한 메시지를 보지 못했기 때문에 확인 메시지를 다시 보내지 않았습니다.

0

귀하의 SendMessageReceive 기능은 아무것도 실제로 않습니다. 그들은 단지 바이트를 보내고받습니다. 그들은 "메시지"에 대한 개념이 없으며 메시지를 보낼 때 메시지의 끝을 표시하지 않고 수신 할 때 메시지의 끝을 인식하지 않습니다. 간단히 말해 네트워크 프로토콜을 구현하는 것을 잊었으며 실제로 TCP가 바이트 스트림 서비스 일 때 메시지 서비스라고 가정합니다.

메시지를 보내고 받으려면 "메시지"가 무엇인지 정의하고 보내고받을 코드를 작성해야합니다. 그것은 마법으로 작동하지 않습니다.

+0

HL7 메시지를 보내고 ACK 응답을 수신 중입니다. 나는 내가 보내고있는 것의 시작과 끝 문자를 안다. 내 가정은 비록 내가받은 것을 열어 보면 내 방향이 그걸로 잡힐 것입니다. 그렇지 않은가요? – Jhorra

+0

원래 질문에서 말했듯이, 나는이 프로젝트를 물려 받았고 소켓의 모든 기술적 세부 사항을 알지 못합니다. 그래서 사리스 (Sarris)의 말에 따르면, "당신이 어릴적 인 것처럼 설명하십시오". 부디. – Jhorra

0

David Schwartz가 지적했듯이 메시지를 구분하는 방법이 필요합니다.

자세히 알아보기 WebSocket data is framed

0     1     2     3 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-------+-+-------------+-------------------------------+ 
|F|R|R|R| opcode|M| Payload len | Extended payload length | 
|I|S|S|S| (4) |A|  (7)  |    (16/64)   | 
|N|V|V|V|  |S|    | (if payload len==126/127) | 
| |1|2|3|  |K|    |        | 
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + 
|  Extended payload length continued, if payload len == 127 | 
+ - - - - - - - - - - - - - - - +-------------------------------+ 
|        |Masking-key, if MASK set to 1 | 
+-------------------------------+-------------------------------+ 
| Masking-key (continued)  |   Payload Data   | 
+-------------------------------- - - - - - - - - - - - - - - - + 
:      Payload Data continued ...    : 
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 
|      Payload Data continued ...    | 
+---------------------------------------------------------------+ 
관련 문제