c# 비동기 소켓프로그램

안녕하세요 소켓 클라이언트 비동기방식으로 만들고 있는데요.
밑에 함수를 15초 마다 타이머로 소켓 서버와 통신 연결 되어있나 확인하는데요.
서버(127.0.0.1:5000)는 꺼져있는 상태에서 프로그램을 새로 시작하거나 통신이 끊겼는데
연결이 되어있다고 되는 경우가 있어서요
어떤 이유인지 확인가능할까요??
client.BeginConnect(ipep, new AsyncCallback(OnConnectCallback), client);
비동기 연결이 살아있어서 그런건가요?
bool IsSocketConnected(Socket s)
{
try
{
return !(s.Poll(1, SelectMode.SelectRead) && s.Available == 0) && s.Connected;
}
catch (SocketException)
{
return false;
}
}

1 Like

안녕하세요.

Q. 서버는 꺼져있는상태에서 프로그램(클라이언트)을 새로 시작할 경우
→ 서버가 정상적으로 종료되지 않아서 발생되는 현상일 수 있습니다. 서버 프로그램도 확인하시면좋을거같습니다.

소켓 서버와 통신연결 확인을 15초마다 해야하는 이유를 알 수 있을까요?
어차피 끊어지면 끊어졌다는 Close 이벤트가 발생될텐데요…?

(다른 분들이 보고 오해하실 수 있을 것 같아서 정정합니다…
동기식 때의 Read시 Blocking만 생각하고… Close이벤트는 참… 오해의 소지를 일으켜서 죄송합니다.)

API 없이는 끊김 감지하기는 어려울겁니다.

  1. Socket.Connected는 연결 끊김을 감지하지 않습니다.
  2. 따라서 Socket.Available가 1 이상인 경우 (!false) && true가 되어 true를 반환하게 됩니다.
  • Socket.Poll 메서드는 네트워크 케이블이 끊어졌거나 원격 호스트가 비정상적으로 종료된 것과 같은 특정 종류의 연결 문제를 검색할 수 없습니다. 이러한 종류의 오류를 감지하려면 데이터를 보내거나 받아야 합니다. (MSDN 참조)
2 Likes

TcpClient.Connected Property

참고 TcpClient.Connected Property (System.Net.Sockets) | Microsoft Learn

The Connected property gets the connection state of the Client socket as of the last I/O operation. When it returns false, the Client socket was either never connected, or is no longer connected.

Because the Connected property only reflects the state of the connection as of the most recent operation, you should attempt to send or receive a message to determine the current state. After the message send fails, this property no longer returns true. Note that this behavior is by design.

You cannot reliably test the state of the connection because, in the time between the test and a send/receive, the connection could have been lost. Your code should assume the socket is connected, and gracefully handle failed transmissions.

Connected 속성은 마지막 I/O 작업 당시 클라이언트 소켓의 연결 상태를 가져옵니다. false를 반환하면 클라이언트 소켓이 연결되지 않았거나 더 이상 연결되지 않은 것입니다.

Connected 속성은 가장 최근 작업의 연결 상태만 반영하므로 현재 상태를 확인하려면 메시지를 보내거나 받아야 합니다. 메시지 전송이 실패한 후에는 이 속성이 더 이상 true를 반환하지 않습니다. 이 동작은 의도적으로 설계된 동작입니다.

테스트와 보내기/받기 사이에 연결이 끊어졌을 수 있으므로 연결 상태를 안정적으로 테스트할 수 없습니다. 코드에서는 소켓이 연결되어 있다고 가정하고 실패한 전송을 적절하게 처리해야 합니다.

3 Likes

이상하네요?? 서버가 종료된 상태에서 클라이언트를 재실행하면 커넥션 에러를 뱉어야하는데… 개인적인 생각이지만 이거는 클라이언트를 볼게 아니라 서버쪽 소켓을 보셔야할 것 같네요? 서버 소켓이 어떠한 이유인지 정상적으로 종료가 안되고 있는거 같습니다. 아마도 재접속말고 처음부터 클라이언트만 실행하면 바로 연결이 안된다고 에러를 뱉을 것 같은데…