2013-08-22 5 views
1

먼저 내가 서버/클라이언트이 코드는 (같은 PC에서 실행되는 클라이언트와 서버 모두) 내 PC에서 잘 작동하는지 말하고 싶은 원격 호스트에 소켓 ReceiveAsync와가 SendAsync에 문제가C 번호 :

문제가 시작 때 전용 서버에서 서버를 호스팅하십시오. 두 번째로 클라이언트와 송수신을 시도하면 클라이언트는 작업을 완료하는 데 많은 시간이 걸릴 것입니다 (1 시간 이상 소요되는 1 바이트의 데이터 수신에 대해 이야기합니다!)

**이 문제를 피할 수 있습니다. 문제가 단순히 연결을 끊고 각 보내기/받기 명령 후 다시 소켓을 연결하여

나는 왜 그때 내가 하나 이상의 보내기/받기 작업을 할 것입니다 많은 시간이 걸리는 이해가 안된다 동일한 연결 세션. 여기


은 예이다 :

서버 연결 :

RC_Server = new SocketConnection_Client(RC_IpEndPoint); 

현재 클라이언트가 서버에 접속되고, 그리고 난 송신/정상적으로 수신 시작할 수있다.

처음으로 보내거나 받으려고하면 버퍼 길이에 관계없이 완벽하고 빠르게 작동합니다. 지금

RC_Server.sendCompleted = false; 
    RC_Server.Send(buffer); //in this case buffer size is 1024 
    while (!RC_Server.sendCompleted) { } //here thread is waiting for the send to complete 

, 전 서버

 RC_Server.receiveCompleted = false; 
     RC_Server.Receive(buffer.Length); //in this case byffer needs to get 4 bytes from server 
     while (!RC_Server.receiveCompleted) { } // <<- Here it will take VERY long time for the operation to complete 
     buffer = RC_Server.buffer; 

두 번째 socket_receiveCompleted_Completed 이벤트에 결코 받기 작업을 함께 수신 세션을 시작합니다.


하지만 .. 난/처음 보낸 후 서버와의 연결을 닫습니다 세션을 수신 한 다음 서버와의 새로운 연결을 열고 다음 보내기/세션을 수신 할 것인지, 다음 모든 것을 완벽하게 작동합니다 . (여러 송/수신에 대해이 방법을 여러 번 복제하십시오.)

또한 동일한 워크 스테이션에서 서버와 클라이언트를 실행해도 문제가 발생하지 않습니다. 그것은 내가 원격 호스트에서 서버를 호스트하는 경우에만 발생합니다.

class SocketConnection_Client 
    { 
     public string errorMsg = string.Empty; 
     public bool receiveCompleted = false; 
     public bool sendCompleted = false; 
     int bytesReceived = 0; 
     public byte[] buffer; 
     Socket socket; 

     public SocketConnection_Client(IPEndPoint ipEP) 
     { 
      socket = new Socket(ipEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
      try 
      { 
       socket.Connect(ipEP); 
      } 
      catch (Exception ex) 
      { 
       errorMsg = ex.Message; 
       socket.Dispose(); 
       socket = null; 
      } 
     } 

     public void Send(byte[] sBuffer) 
     { 
      buffer = null; 
      if (socket == null) 
      { 
       sendCompleted = true; 
       return; 
      } 
      sendCompleted = false; 

      SocketAsyncEventArgs socket_sendCompleted = new SocketAsyncEventArgs(); 
      socket_sendCompleted.SetBuffer(sBuffer, 0, sBuffer.Length); 
      socket_sendCompleted.Completed += socket_sendCompleted_Completed; 
      socket.SendAsync(socket_sendCompleted); 
     } 

     void socket_sendCompleted_Completed(object sender, SocketAsyncEventArgs e) 
     { 
      sendCompleted = true; 
     } 

     public void Receive(int bLength) 
     { 
      bytesReceived = 0; 
      buffer = null; 
      if (socket == null) 
      { 
       receiveCompleted = true; 
       return; 
      } 
      receiveCompleted = false; 

      buffer = new byte[bLength]; 
      SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs(); 
      socket_receiveCompleted.SetBuffer(buffer, 0, buffer.Length); 
      socket_receiveCompleted.Completed += socket_receiveCompleted_Completed; 
      socket.ReceiveAsync(socket_receiveCompleted); 
     } 

     private void Receive_Continue() 
     { 
      SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs(); 
      socket_receiveCompleted.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived); 
      socket_receiveCompleted.Completed += socket_receiveCompleted_Completed; 
      socket.ReceiveAsync(socket_receiveCompleted); 
     } 

     void socket_receiveCompleted_Completed(object sender, SocketAsyncEventArgs e) 
     { 
      bytesReceived += e.BytesTransferred; 
      if (e.BytesTransferred == 0 && bytesReceived == 0) 
      { 
       socket.Dispose(); 
       socket = null; 
       receiveCompleted = true; 
       throw new Exception("Server Disconnected"); 
      } 
      else if (bytesReceived != buffer.Length) 
       Receive_Continue(); 
      else 
       receiveCompleted = true; 
     } 
    } 

감사 : 여기

내 소켓 클래스의 일부입니다. 감사합니다. .

답변

0

ReceiveAsync에서 반환 값을 무시합니다. the documentation에주의 -이 두 가지 행동은 당신이 그들을 구별하는 반환 값을 확인해야합니다 : I/O 작업이 보류되고있는 경우는 true

반환은. e 매개 변수의 SocketAsyncEventArgs.Completed 이벤트는 작업 완료시 발생합니다.

I/O 작업이 동 기적으로 완료되면 false를 반환합니다.이 경우 e 파라미터에 SocketAsyncEventArgs.Completed 이벤트 제기되지 않으며 매개 변수로 전달 된 e 객체 메소드 호출의 동작의 결과를 검색하기 위해 반환 직후에 조사 될 수있다.