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 및 이전 버전에서는 연결을 닫기 전에 스트림을 수동으로 닫아야했습니다. 이 버그는 TcpClient
C # 의 모든 최신 버전에서 수정되었으며 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
.
그러나 옵션이 있습니다 LingerState
온 TcpClient
이 문제를 해결 한 수 표시 (내 자신의 하드웨어 설정은 종종 그것에 대해 실패로 몇 달 동안 모를 수는!). 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 모든 연결 이 있는지 확실 합니까?
'Development Tip' 카테고리의 다른 글
날짜 시간 asc로 PostgreSQL 정렬, 먼저 null입니까? (0) | 2020.11.07 |
---|---|
Python 2.7에서 HTTP 프록시를 설정하는 방법은 무엇입니까? (0) | 2020.11.07 |
Rails, MySQL 및 Snow Leopard (0) | 2020.11.07 |
jQuery로 HTML 주석 선택 (0) | 2020.11.07 |
C #의 부분 클래스는 잘못된 디자인입니까? (0) | 2020.11.07 |