본문 바로가기
생활정보

TCP/IP 우아한 종료 때문에 민망했던 경험

by vicddory 2019. 4. 13.

바야흐로 자신감이 하늘을 찌르다 못해 건방지게 굴던 2년차 시절. 그때는 세상 모든 일이 만만해 보이고 나는 뭐든 잘 해내리란 확신이 있었다. 이런 생각으로 1년을 보내고 2년차를 보내던 시기였다.


TCP/IP 소켓 활용한 클라이언트 프로그램을 작성하여 나름대로 테스트를 끝내고 당당하게 팀장님께 말씀드렸다.


"다 했습니다. 장비에 적용할까요?"


그런 나를 팀장님은 지긋이 바라보며, 이렇게 말씀하셨다.


"그래? 그럼, 테스트 꼼꼼하게 해 보자. 따라와"


그게 망신당하기 문으로 들어가는 것일 줄이야. 그땐 몰랐지. 그때도, 지금도, 나는 나보다 경력 많은 사람이 무조건 부럽다. 그들의 경험과 생각은 풍부하기 때문에.

어쨌든, 당시 팀장님은 서버 프로그램 띄울 PC, 내가 작업한 장비 프로그램 띄울 PC 2대를 준비하셨다. 그리고 핸드쉐이킹을 체크하며 장비 제어를 정상적으로 할 수 있을지 테스트 프로그램을 실행하셨다. 내 예상대로 테스트 프로그램에선 오류가 발견되지 않았다. 통신이 정상적이며, 잘못된 패킷 등을 잘 걸러내는 것이 확인되었다.


그러다 팀장님은 갑자기 서버 프로그램이 돌아가는 PC를 강제로 껐다. 그러자 내가 작업한 프로그램은 응답없음 상태, 그러니깐 블록 상태로 바뀌었다.


핵심은 이것이다.


반드시 수신 데이터를 받아야 하는 치명적 오류


그렇다. 통신이 안 될 때를 고려하지 못한 것이다. 사실, 커넥션 오류는 준비했지만, 구현이 미비했다.


TCPIP 우아한 종료 때문에 민망했던 경험


서버와 클라이언트는 각각 send, recv 함수를 이용해 데이터를 주고받는다. 프로그램 종료, 윈도우 에러 등으로 발생하는 커넥션 오류는 걸러낼 수 있었으나, 비정상적으로 PC가 종료된 경우를 분별하지 못했다. 그러니 recv 함수가 동작하지 않아 10분, 20분, 1시간, 2시간이 지나도 send 함수가 반복 실행될 뿐이었다.


이 때문에 블록 현상이 발생한 것이다.


해결 방법은 간단했으나, 왜 이걸 알지 못했을까?


그동안 내 선임 개발자들이 작성한 소스 코드를 제대로 보지 않은 것이다. 이미 사내 솔루션 소스에는 이 부분까지 고려한 예외처리 소스가 있었다. 내가 보고도 인지하지 못했다. 내 실수였지.


패킷 주고받는 프로그램이야 누구나 만들 수 있다. 그리고 그 프로그램을 현장에 적용할 수도 있다. 그러나, 예외처리를 고려하여 문제 발생 시 프로그램이 구동하는 방법은 아무나 만들 수 없다. 경험과 인내와 현장 지식이 있어야 한다. 


당시 팀장님은 어느 부분에 어떤 소스가 있는지 말씀해 주셨고 나는 그 소스를 내가 작업하던 프로그램에 적용할 수 있었다. 그러나 다른 문제가 발생했다.


  • 에러를 재현할 줄 몰랐다.
  • 어떻게 해야 에러가 발생할까?


우아한 종료 소켓 tcp ip


그래서 선임 개발자들이 작성한 문서를 읽었다. 그제야 텍스트들이 내 지식이 되었다. 고객사에서 올라온 장애 리포트들이 그제야 이해되었다. 그리고 소스를 보니 왜 여기에 이런저런 코드가 추가되었는지 이해할 수 있었다. 왜 나는 이제야 알게 되었을까? 나의 머리를 스치던 내 생각이었다.


제목엔 우아한 종료라고 적었으나, 따지고 보면 사내 소스 코드, 문서를 이해하지 못했던 민망한 경험이었던가? 사실, 경험이 없는 나에게 팀장님이 설명해 봐야 어차피 이해하지 못했을 것 같기도 하다. 이런 경험이 쌓여야 이해하겠지.


당시 자신 있게 이야기하며 목소리가 커졌던 나는 굉장히 민망했었다. 그리고 며칠 동안 조용히 이전 소스와 문서를 꼼꼼히 읽었다. 그리고 그다음 주엔 머리가 좀 커졌다고 예전처럼 건방지게 회사를 다녔다.



관련 글


Qt TCP 이더넷 연결 끊김 상태 확인 (QTcpSocket 소켓 플러그 뽑힘)

C# 안드로이드 연동, TCP 통신 소켓 예제 소스

C# 비동기 Async, 소켓 서버, 함수 소스 (Socket network)



ⓒ written by vicddory

댓글