클라이언트 소켓에서 송신 오류를 내는(?) 방법
글쓴이: munamuna / 작성시간: 수, 2009/06/10 - 10:26오전
안녕하세요.
이거 제목을 뭐라 달아야 할지 좀 난감해서 의미 불명의 제목이 됐습니다.
완성된 클라이언트를 테스트 하기 위해 테스트 서버를 만들어야 합니다.
클라이언트는 테스트 서버에 접속한 후에 바로 데이터를 송신하는데요..
이때 송신 실패가 발생하도록 테스트 서버를 만들어야 합니다.
(당연히 클라이언트는 손대면 안되지요)
그래서 테스트 서버에서 accept()한 후에, 취득되는 차일드 소켓을 바로 close()하도록 작성했습니다.
클라이언트는 connect(sock) => send(sock)
서버는 listen(listen_sock) => clnt_sock = accept(listen_sock) => close(clnt_sock)
이런 절차를 거치게 됩니다.
그런데.. 이상하게도 클라이언트에서 송신 에러가 발생하지 않기에 뭐가 잘못된거지? 하고 소켓 상태를 보니, 서버에서 바로 클라이언트 소켓을 close()해도 소켓의 상태는 CLOSE_WAIT 상태가 되어버리더군요.
때문에 클라이언트에서는 send()가 성공하고, recv()할때서야 "소켓이 종료되었음"을 알 수가 있습니다.
테스트 서버를 어떻게 작성해야 클라이언트의 send()에서 오류가 발생하게 할 수 있을련지요?
조언 부탁드립니다.. __);
Forums:
client 수정이 필요할 듯
일단 client가 send를 recv보다 먼저 호출하니 server가 close했다는 FIN을 application에서 인지를 못하는 상황이라서 recv때에야 에러를 감지하는 상황이구요.
send가 성공하는 이유는 2가지 경우가 가능할 것 같습니다.
1. server에서 close호출 -> client가 아직 정상 상태 -> send호출.
2. server에서 close호출 -> client가 CLOSE_WAIT상태 -> send호출.
1번은 FIN이 client에 도착하기 전에 send가 호출되는 경우이고
2번의 경우가 좀 희한하다면 희한한 데요. CLOSE_WAIT상태에서 socket에 write하면 결국 server쪽에서 RST을 client에 보냅니다. 그러니까 최초 send는 return값이 성공이고 한번 더 send를 하면 EPIPE가 errno에 setting됩니다.
최초의 send에서 오류를 발생(?)하게 하려면 server수정으론 힘들어 보입니다.
아무래도 client를 수정하셔야 할 듯 하네요. send전에 select를 걸어서 읽어보는 방법밖엔 생각이 안나네요.
P.S.
혹시 2번 경우에 왜 저렇게 정해졌는지에 대해 자세히 설명해 주실 수 있는 분이 계시면 좀 부탁드립니다. 대충은 감이 올듯 말 듯 한데 저렇게 안했을 경우 꼬이는 경우를 생각하려니 머리가 안돌아 갑니다.
답변감사드립니다. __);
음.. 아무래도 님 말씀대로 클라이언트 수정이 필요한듯 싶네요..
send하기전에 select를 거는게 제일 확실하고, 흐름상 영향도 없으니 이걸로 가야할듯 싶습니다.
감사드려요.. ^^
댓글 달기