인프런 커뮤니티 질문&답변
UnhandledException 으로 서버 터지는 경우
작성
·
27
0
안녕하세요,
해당 강의에서 만든 코드 기반으로 제 게임에 맞춘 서버를 AWS EC2에서 몇 주째 실행중입니다. 개발 컴퓨터에서 테스트할때도 그렇고 EC2에서 할때도 그렇고 강제 종료될때가 있어서 꺼지면 로그 남기게 해서 몇개 원인을 찾았는데요, UnhandledException이 뜨면서 강제종료 되는 경우가 두가지 있는 것 같습니다.
제 유추 상으로는 포트포워딩으로 게임 포트 이외에는 인바운드를 거절했는데도 쓰레기IP들이 서버를 터트리고 가는 것 같습니다.
첫번째.
[11-24 18:31:38] FATAL [UnhandledException]
System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
at System.Net.Sockets.Socket.Shutdown(SocketShutdown how)
at ServerCore.Session.Disconnect() in \Server\ServerCore\Session.cs:line 103
at ServerCore.Session.OnRecvCompleted(Object sender, SocketAsyncEventArgs args) in \Server\ServerCore\Session.cs:line 193
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__173_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading.ThreadPoolTypedWorkItemQueue`2.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()이 오류는 Session.cs에 소켓 Shutdown에서 발생했습니다.
public void Disconnect() {
if (Interlocked.Exchange(ref _disconnected, 1) == 1)
return;
OnDisconnected(_socket.RemoteEndPoint);
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
Clear();
}서버가 터지면 안되니 임시 방편으로 try catch로 감싸놨습니다.
try {
_socket.Shutdown(SocketShutdown.Both);
} catch (Exception e) {
Console.WriteLine($"[NEW ADDED] SOCKET SHUTDOWN Failed {e}");
}
try {
_socket.Close();
} catch (Exception e) {
Console.WriteLine($"[NEW ADDED] SOCKET CLOSE Failed {e}");
}
두번째.
[11-25 10:16:12] FATAL [UnhandledException]
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.get_RemoteEndPoint()
at ServerCore.Listener.OnAcceptCompleted(Object sender, SocketAsyncEventArgs args) in Server\ServerCore\Listener.cs:line 45
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__173_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading.ThreadPoolTypedWorkItemQueue`2.System.Threading.IThreadPoolWorkItem.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
--------------------------------------------------이 오류는 Listener.cs의 RemoteEndPoint를 가져오는 부분에서 발생했는데요,
void OnAcceptCompleted(object sender, SocketAsyncEventArgs args) {
if (args.SocketError == SocketError.Success) {
Session session = _sessionFactory.Invoke();
session.Start(args.AcceptSocket);
session.OnConnected(args.AcceptSocket.RemoteEndPoint);
} else
Console.WriteLine(args.SocketError.ToString());
RegisterAccept(args);
}비쥬얼 스튜디오에서도 args.AcceptSocket.RemoteEndPoint 는 null일수도 있다고 뜨기는 하는데
이부분도 != null을 붙여서 해야하는지 try catch로 감싸야하는지 궁금합니다.
근본적인 원인은 예외가 왜 발생하는지 알아야하는데 전부 API 단이라 try catch 혹은 != null 빼고는 대책을 강구하기가 어렵습니다.
요약하자면
이런 UnhandledException이 나올때 해당 코드를 try { } catch로 해주것이 괜찮은 방법인가요?
혹시 근본적인 해결책이 있다면 궁금합니다.
답변 2
0
와우 잘 찾으셨습니다.
강의에선 누락 되었으나 C# 네트워크 관련 함수 호출할 땐
싹 다 try-catch를 해주시는 것이 맞습니다.
M2 프로젝트에서는 저런 부분 보완 처리 코드도 추가 되었던 것으로 기억합니다.
0
안녕하세요, 인프런 AI 인턴입니다. 아휘님께서 겪고 있는 문제는 네트워크 프로그래밍에서 종종 발생할 수 있는 연결 문제와 관련된 사항입니다. 두 가지 사례에 대해 하나씩 살펴보겠습니다.
첫 번째 오류: SocketException - “An existing connection was forcibly closed by the remote host.”
이 오류는 일반적으로 네트워크 연결이 예기치 않게 끊어진 경우에 발생합니다. 예를 들어, 클라이언트가 서버와의 연결을 강제로 닫았을 때 발생할 수 있습니다. 다음과 같은 조치를 고려할 수 있습니다:
예외 처리: 이미 시도하신 대로
try-catch로 소켓의Shutdown과Close를 감싸는 것은 올바른 접근 방식입니다. 네트워크 환경에서는 예상치 못한 오류가 발생할 수 있기 때문에 이러한 예외 처리가 필요합니다.로그 기록: 오류 발생 시 로그를 통해 문제가 발생한 상황을 기록하여 원인을 분석하는 데 도움이 될 수 있습니다.
두 번째 오류: ObjectDisposedException - “Cannot access a disposed object.”
이 오류는 이미 해제된 소켓 객체에 접근하려 할 때 발생합니다. 이는 네트워크 비동기 작업이 완료되기 전에 소켓이 제대로 해제되지 않았을 때 생길 수 있습니다.
null체크 추가:AcceptSocket이null인지 확인한 후에RemoteEndPoint를 접근하도록 코드를 수정할 수 있습니다.if (args.AcceptSocket != null && args.SocketError == SocketError.Success) { Session session = _sessionFactory.Invoke(); session.Start(args.AcceptSocket); if (args.AcceptSocket.RemoteEndPoint != null) { session.OnConnected(args.AcceptSocket.RemoteEndPoint); } }코드 흐름 점검: 연결 수립과 소켓 상태 관리를 철저히 점검하여 비동기 작업 중 소켓 객체가 폐기되지 않는지 확인하는 것이 중요합니다.
전반적인 조언
예외 처리 관행: 각 네트워크 작업에 대해 예외 처리를 도입하는 것은 네트워크 프로그래밍에서 필수적입니다. 예외 처리를 통해 프로그램이 비정상 종료되지 않도록 관리할 수 있습니다.
근본적인 해결책: 근본적인 해결책을 찾기 위해서는 네트워크 흐름의 모든 단계에서 문제를 파악하고 처리할 수 있는 예외를 정의하는 것이 중요합니다. 또한, 네트워크 보안을 강화하고 외부 비정상 트래픽을 차단하는 장치를 사용해 보실 것을 권장합니다.
관련된 유사한 질문과 답변은 다음 링크에서 확인하실 수 있습니다:
- “프로그램 에러 관련 질문…”
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.






감사합니다 ^^ 사랑합니다!!!!★