2013-08-28 7 views
3

클라이언트 서버 응용 프로그램을 만들고 있습니다. 서버는 이미 클라이언트로부터의 연결을 기다리고있는 설계 및 장소에 있습니다. 이제 클라이언트 섹션에서 응용 프로그램의 수명 내내 연결을 유지하고 싶습니다. 연결은 주 클라이언트 응용 프로그램을 닫거나 종료하거나 서버를 닫을 때만 닫힙니다.Tcp 연결 유지

는 현재 10 초마다 서버는 TCP connection.I이

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true); 

과 노력 닫지 만 나를 위해 작동하지 않습니다 .. 다음은 내 코드 블록

public TCPStreamDevice(string RemoteIPAddress, int RemotePort, string SourceIPAddress, int SourcePortNo)   
{ 
    mIpAddress = RemoteIPAddress; 
    mPort = RemotePort; 

    mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    System.Net.IPEndPoint LocalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(SourceIPAddress), SourcePortNo); 

    mClient.Bind(LocalEndPoint); 

    mDataReceivedCallback = new AsyncCallback(DataReceivedTCPCallback_Handler); 
    mBuffer = new byte[1024]; 
    Description = new DeviceDescription(); 
} 

과에 다루는 사람 :

private void DataReceivedTCPCallback_Handler(IAsyncResult ar) 
{ 
    try 
    { 
     Socket client = (Socket)ar.AsyncState; 
     int bytesReceived = client.EndReceive(ar); 

     if (bytesReceived > 0) 
     { 
      //to know transport level errors 
      //EngineInterface.reponseReceived(mBuffer, false); 

      ReceiveCallBackFunc(mBuffer, bytesReceived); 

      client.BeginReceive(mBuffer, 0, 1024, SocketFlags.None, DataReceivedTCPCallback_Handler, client); 
     } 
     else 
     { 
      //disconnect 
      /* when there is no datapacket means no TCP connection is alive now (how can i keep Tcp alive here) */ 
     } 
    } 
} 
+1

아마도 서버가 연결을 종료했을 것입니다. 시간 초과가 초과되면 10 초 이내에 데이터를 전송하는 것을 제외하고는 아무 것도 할 수 없습니다. 수신 된 0 바이트는 다른 쪽이 연결 해제되었음을 의미합니다. –

+0

거기에 어떤 방법을 통해 나는 TCP 세션을 다시 시작할 수 있습니까? –

+0

필요할 때 다시 연결해야합니다. 이것은로드가 많은 서버의 경우 일반적으로 발생합니다. –

답변

1

의견 ("데이터 패킷이 없다는 것은 TCP가 없음을 의미합니다. 연결 ")는 상대방으로부터 연결 해제 (0 바이트) 패킷을 수신하는 곳에 배치됩니다. 다른 쪽 을 선택하여 닫히기 때문에 을 연결하는 것이 가능합니다. 연결이 살아 있습니다.

네트워크 문제로 인해 연결이 닫히면 예외가 발생하거나 연결이 유효하지만 조용한 것처럼 보입니다.

Keep-alive 메커니즘은 항상 시간 초과와 함께 작동합니다. 시간 제한은 "x 초 동안 데이터를 수신하지 못하면 연결을 닫습니다"는 제한을 적용합니다. 여기서 keep-alive는 단순히 시간 만료를 유지하기 위해 더미 데이터 패킷을 보냅니다.

TCP/IP 수준에서 작동하는 프로토콜을 직접 구현하면 다른 쪽에서 이미 시간 제한이 구현되어있는 경우에만 연결 유지를 구현하면됩니다.

+0

살아있는 타이머를 유지하는 방법을 구현하는 방법은 무엇입니까? 당신은 이것에 관해 나를 도와 줄 수 있겠습니까? 내가 자습서에서 살아남 으려고했는데 ... 그들은 작동하지 않습니다. –

2

위의 댓글과 답변은 유효합니다. 앱의 전체 수명 동안 소켓을 열어 제대로 작동 할 것으로 예상되는 디자인이 잘못된 것처럼 들리므로 연결에 대비하여 어떤 종류의 오류 방지 메커니즘을 구축해야합니다 떨어졌다.

Keep-alives로 돌아 가기 : 서버와 클라이언트의 양쪽 끝에서 소켓이 양쪽에 어떻게 설정되어 있는지 확인하십시오. keep alive의 기본 값은 2 시간이라고 생각합니다. keep-alive 패킷을 기다리는 데 오랜 시간이 걸리지 만 변경 될 수 있습니다. Socket.IOControl 메서드를 확인하고 IOControlCode.KeepAliveValues과 같은 구조 (관리되지 않음) http://msdn.microsoft.com/en-us/library/ms741621.aspx을 사용하십시오. 제어 코드에 대한 자세한 내용은 여기를 참조하십시오. http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode.aspx

0

서버에서 소켓을 만들 때 IOControlCode.KeepAliveValues를 설정하여 TCP KeepAlive를 설정할 수 있습니다. 코드 프로젝트의 아래 기사는 그것을 아주 잘 설명합니다. SocketOptionLevel.Tcp 수준에서 대신 SocketOptionLevel.Socket를 사용 SetSocketOption()에 대한 호출에서

Sample on How-To set keep alive values

6

KeepAlive가 유효하지 않습니다.

SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

+0

또한 소켓에'keepalivetime'과'keepaliveinterval' 설정을해야합니다. 'SetSocketKeepAliveValues'와'SetTcpKeepAlive'를 검색하십시오 –