socket close 문제
tcp/ip socket을 써서 여러개의 파일을 보내는 프로그램입니다.
server는 새로운 접속 시도를 받을때마다 쓰레드를 하나씩 만들어서
recv()를 반복합니다. recv결과가 -1이면 socket을 shutdown, close 합니다. client쪽 소켓이 강제로 닫히면 recv에러를 내면서 shutdown됩니다.
client에서는 3개의 쓰레드 수 제한을 두고 서버에 접속해서 각각 하나의 파일을 맡아서 40kB씩 쪼개서 반복적으로 보냅니다. 파일 크기는 0byte에 가까운 것부터 1GB에 달하는것까지 다양합니다. send 에러가 발생하거나 connect에 실패할 경우에 소켓을 닫습니다.
한 서버에 대해 클라이언트 14개가 한꺼번에 돌때(파일전송 시도) 문제가 발생합니다.
localhost로 테스트할때는 잘 됐는데 network사정이 조금 좋지 않은데서 시도한 결과 모든 파일 전송이 끝난 후 send error가 발생했는데 client에서는 연결이 모두 끊겼는데(client 프로그램이 전혀 떠 있지 않습니다. netstat으로 봐도 없고) server쪽에서는 몇몇 연결이 recv상태로 기다리고 있더군요 -.- blocking recv라서..한쪽 socket이 닫혔는데 다른쪽에서 recv상태로 버티고 있는게 가능한가요? netstat에서도 Established로 보이더군요. client쪽은 해당 포트가 열려있지 않구요.
send error나는건 어쩔수 없다고 해도 socket열린상태로 있는건(부수적으로 파일도 열린상태로 있게 됩니다.) 꼭 막아야 하는데.
server 프로그램 죽였다가 살리면 되긴 하지만 말그대로 서버라서 죽이는건 좋지 않고
원인이 무엇일까요?
이 경우를 방지하기 위해서는 어떻게 해야 할까요?
(이전에 쓰레드가 10개일때보다는 빈도가 확실히 줄었는데.. 쓰레드를 더 줄여야 할까요?)
recv 시간제한을 1분정도로 두어도 될 것 같은데 어떤식으로 구현할지 잘 모르겠습니다.
소스가 너무 방대해서 여기 올릴수가 없고(사실 제가 짠것도 아니고요..분석만 했습니다.) 대충 설명을 드렸는데 설명이 허잡해서 죄송스럽군요. 이정도만 보시고 추정되는 원인이나 해결방법 말씀해주시면 감사하겠습니다.
[url]http://bbs.kldp.org/viewtopic.php?t
http://bbs.kldp.org/viewtopic.php?t=19969&highlight=
위에 링크를 참조하세요~
.
recv 결과 0도 체크해 보세여..
man recv
음 저의 경우를 얘기해볼까 합니다.recv에서 (-1)이 리턴 되
음 저의 경우를 얘기해볼까 합니다.
recv에서 (-1)이 리턴 되는 경우는 그냥 끊어진걸로 판단하는것은
별로 큰 문제가 없다고 생각하여 저도 그렇게 처리합니다.
하지만 0이 리턴되도 끊어진것일수 있습니다.
저는 복잡하게 구현하지 않으려고
select가 걸렸을때 FIONREAD를 ioctl로 읽어와서
값이 0이면 끊어진 것으로 추가처리하고 사용합니다.
0이 아닌 값이 올라오면 이때 recv를 사용합니다.
select는 timeout 뿐만 아니라 socket이 끊어질때도 block에서
빠져나오는 특성을 먼저 이용하고 그 다음에 socket buffer를 검사한다는
발상이죠.
지금까지 잘 돌고 있고 문제점이 없는거 같습니다.
댓글 달기