Development Tip

TcpClient 연결을 적절하고 완전히 닫거나 재설정하는 방법은 무엇입니까?

yourdevel 2020. 11. 7. 10:34
반응형

TcpClient 연결을 적절하고 완전히 닫거나 재설정하는 방법은 무엇입니까?


TcpClient 연결을 닫거나 재설정하는 올바른 방법은 무엇입니까? 하드웨어와 통신하는 소프트웨어가 있지만 때때로 문제가 발생하여 소프트웨어를 다시 시작할 때까지 더 이상 통신 할 수 없습니다.

TcpClient.Close ()를 강제로 시도하고 null로 설정했지만 작동하지 않습니다. 소프트웨어를 완전히 다시 시작해야만 작동합니다.

제안?


TpcClient는 한 위치에만 정의되어 있지만 라이브러리 전체에서 사용되기 때문에 using 키워드를 사용할 수 없습니다. (그리고 주어진 시간에 하나의 연결 만 있습니다)

커뮤니케이션을 처리하는 라이브러리입니다. 소프트웨어 자체는 하드웨어를 나타내는 Controller 클래스의 ResetConnection () 메서드를 호출 할 수 있습니다.

현재는

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

이제 여기에서 읽은 내용에서 "= null"대신 tcpClient.Dispose ()를 사용해야합니다.

나는 그것을 시도하고 그것이 차이를 만드는지 볼 것입니다.


연결을 닫기 전에 스트림을 닫아야합니다.

tcpClient.GetStream().Close();
tcpClient.Close();

클라이언트를 닫아도 스트림이 닫히지 않습니다.


사용 단어 : using. 좋은 프로그래밍 습관.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

수락 된 답변이 구식이고 이것에 관한 다른 답변에는 아무것도 보이지 않는다는 점을 감안할 때 새 답변을 만들고 있습니다. .Net 2 및 이전 버전에서는 연결을 닫기 전에 스트림을 수동으로 닫아야했습니다. 이 버그는 TcpClientC # 의 모든 최신 버전에서 수정되었으며 Close 메서드 의 문서에 명시된대로 메서드 를 호출 Close하면 연결과 스트림이 모두 닫힙니다.

Microsoft Docs에 따라 편집

Close 메서드는 인스턴스를 삭제 된 것으로 표시하고 연결된 Socket이 TCP 연결을 닫도록 요청합니다. LingerState 속성에 따라 TCP 연결은 데이터를 계속 보낼 때 Close 메서드가 호출 된 후 얼마 동안 열려있을 수 있습니다. 기본 연결이 종료되면 알림이 제공되지 않습니다.

이 메서드를 호출하면 결국 연결된 소켓이 닫히고 데이터를 보내고받는 데 사용되는 연결된 NetworkStream도 닫힙니다.


소켓 연결을 닫고 소켓의 재사용을 허용합니다.

tcpClient.Client.Disconnect(false);

일부 내부 로깅을 제외하고 Close == Dispose.

Dispose는 tcpClient.Client.Shutdown (SocketShutdown.Both)을 호출하지만 오류가 발생합니다. 직접 호출하면 유용한 예외 정보를 얻을 수 있습니다.


다시 열 수 있도록 소켓을 닫는 올바른 방법은 다음과 같습니다.

tcpClient.Client.Disconnect(true);

Boolean 매개 변수는 소켓을 재사용할지 여부를 나타냅니다.

연결 해제 방법 사용


모든 적절한 using명령문을 가지고 있음에도 불구하고 , 호출 Close, 지수 백 오프 논리 및 TcpClient다시 생성 응용 프로그램을 다시 시작하지 않으면 응용 프로그램이 TCP 연결을 복구 할 수없는 문제가 여전히 발생했습니다. 계속해서 System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

그러나 옵션이 있습니다 LingerStateTcpClient이 문제를 해결 한 수 표시 (내 자신의 하드웨어 설정은 종종 그것에 대해 실패로 몇 달 동안 모를 수는!). MSDN을 참조하십시오 .

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...

TcpClient.Dispose ()를 명시 적으로 호출 해 보셨습니까 ?

그리고 TcpClient.Close () 및 TcpClient.Dispose ()-ed 모든 연결 이 있는지 확실 합니까?

참고 URL : https://stackoverflow.com/questions/425235/how-to-properly-and-completely-close-reset-a-tcpclient-connection

반응형