클라이언트가 TCP RST을 하는 이유
글쓴이: mandugukbap / 작성시간: 화, 2013/05/14 - 10:26오후
C언어 기반의 TCP 소켓에서 다음과 같은 문제가 발생했습니다.
1) A와 B는 똑같이 구성되어 있고 동일한 파일이 저장되어 있는 웹서버입니다. A와 B는 똑같은 도메인 주소 (aaa.bbb.ccc.com) 을 가지고 있지만 IP 주소가 다릅니다.
2) 제가 만든 프로그램은 웹서버A와 웹서버B에 동시에 접속해서 파일의 1%~50% 부분은 A에 요청하고, 51%~100%까지의 파일 부분은 B에 요청합니다.
3) 제가 만든 프로그램은 A로 먼저 접속을 열고 다운을 받다가 어느 시점에 (예, 10% 다운로드 시점) B로 접속을 요청합니다.
문제: 제가 만든 프로그램이 A와 B 모두에 RST을 보내서 다운로드가 끊어져 버립니다.
- B로 접속을 하고 request를 보내는 것은 문제가 없음이 확인 되었습니다.
- B에서 돌아오는 response 메세지를 소켓의 read() 또는 recv() 함수에서 printf() 해보려 했는데 안됍니다.
- TCPDump로 레코딩을 했을 경우에는 B에서 전달된 response 메세지가 기록되어 있습니다.
제가 만든 프로그램이 A와 B로 RST을 보내는 이유가 과연 무엇일까요? 조그만 힌트라도 큰 도움이 되겠습니다.
감사합니다.
Forums:
TIME_WAIT 없애는 법으로 검색
TIME_WAIT 없애는 법으로 검색 해보세요
웹서버의 RST는 TIME_WAIT와 관련이 있습니다
웹서버가 RST을 시키는게 아니고 제가 만든
웹서버가 RST을 시키는게 아니고 제가 만든 프로그램이 RST을 합니다. 저는 프로그램에 RST을 하는 루틴을 넣지 않았거든요.
wireshark로 캡쳐한 패킷 플로우를
wireshark로 캡쳐한 패킷 플로우를 올려보세요
정확한 진단을 위해선 패킷플로우나 코드 없이는 힘들거 같네요
TCP 패킷들만 필터해 보았습니다. IP 주소는
TCP 패킷들만 필터해 보았습니다. IP 주소는 익명화를 위해 바꾸었습니다. 1.1.1.1이 클라이언트이고 2.2.2.2와 3.3.3.3은 서버입니다.
close 때문인 것 같습니다. RST가 FIN
close 때문인 것 같습니다.
RST가 FIN 이후에 나오는 경우는 SO_LINGER 때문이지만,
RST만 나온 것을 봤을 때 socket rcv buffer에 데이터가 남아 있는데 close()를 호출한 것이 아닐까 생각됩니다.
확인을 위해 close()하기 전에 ioctl(fd, FIONREAD, &ret_nread)를 호출해서
socket rcv buffer에 남아있는 데이터가 있는지 확인해보시기 바랍니다.
해보시고 맞는지 틀렸는지 결과 부탁 드립니다.
참고로 close()대신에 shutdown()을 사용하면 rcv buffer에 데이터가 있어도 RST를 보내지 않습니다.
========================================
* The truth will set you free.
문제를 해결하고 감사와 함께 결과를 알려 드리고
문제를 해결하고 감사와 함께 결과를 알려 드리고 싶었는데, 사실 버퍼에 당연히 데이터가 남아 있을 것이기에 특별히 확인을 하지 않았습니다.
왜냐하면 제 프로그램은 어디에서도 close()나 shutdown()을 호출하지 않기 때문입니다. 다운로드가 완료되면 그냥 프로그램이 종료됩니다. (나중에 제대로 만들때는 close()를 하겠지만 현재는 어디까지나 아이디어의 proof 단계라서요.)
아무튼 서버로부터 다운로드가 진행되는 과정 중간에 RST을 보내고 중단되어 버리니 버퍼에 데이터가 분명 있을 것이라 봅니다.
아무튼 정확히는 아니더라도 문제가 발생하는 과정은 알아 내었습니다. 다만 왜 이런 문제가 생기는지 궁금한데, 새로운 쓰레드를 열어서 질문을 드려야 할지 아니면 이 쓰레드에 계속 문제점을 논하는게 좋을지 모르겠네요.
아무튼 힌트 감사 드립니다.
프로세스를 종료 시키면 시스템이 close를 해주므로
프로세스를 종료 시키면 시스템이 close를 해주므로 위와 똑같은 결과를 가져옵니다.
이미 닫힌 소켓에 패킷이 수신되므로 시스템이 RST를 발생시키는 것이죠.
명시적으로 소켓을 닫지 않고 프로세스를 종료 시키는 방식은 권장하지 않습니다.
========================================
* The truth will set you free.
#163과 #169 ~ #172까지 보시면
#163과 #169 ~ #172까지 보시면 클라이언트가 양쪽 서버에 RST을 보내고 있습니다.
댓글 달기