send() 후 바로 close()하는 경우..
글쓴이: towngo / 작성시간: 목, 2003/04/03 - 8:39오전
패킷 하나를 send()로 보냈습니다..
그리고 바로 send한 소켓을 close 했습니다..
if(send(sock, &packet, sizeof(packet), MSG_DONTWAIT) < 0) { // error 처리.. return 0; } close(sock);
이런 구조인데욤..
받는 쪽 - 윈도우입니다 - 에선 close 하기 바로 전에 패킷을 못받네요..
send한것보다 close가 먼저 될수 있나요?
항상 이렇네요.. -_- +
Forums:
send했다고 해서 바로 보내지지 않습니다.버퍼에 쌓아두고 버퍼가
send했다고 해서 바로 보내지지 않습니다.
버퍼에 쌓아두고 버퍼가 차거나 일정 시간이 지나야
실제로 데이타를 보내게 됩니다.
이때 close/closesocket을 하면 ㅡ_-) 버퍼에 있는 녀석을
보내지 않고 바로 소켓 자원을 OS에게 반환해버립니다.
소켓이 닫히기 전에 보내지 않은 데이타를 완전히 보내기 위해서는
shutdown(sockfd, 2)를 해서 graceful close를 해줘야합니다.
그냥 close하기 전에 앞에 shutdown 한 번 해주면 ㅡ_-) 될 수 있습니다.
send하면 바로 보내려면 setsockopt로 TCP_NODELAY 옵션을 줄 수도
있다고 합니다.
또한 LINGER계열 옵션으로 LINGER를 꺼버리면 shutdown해도
graceful close가 되지 않습니다.
_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz
움...
음.. shutdown()두 해 봤는데욤.. 역시나 안돼는군요.. T^T
별다른 sockopt두 준게 없는데.. 말씀하신대로 TCP_NODELAY 을 줘 봐야겠네요.. :)
웅.. linux끼리는 잘 되는뎅.. 왜 윈됴랑 붙기만 하면 문제가 생기는걸까.. -_-+
send() 리턴을 한번 찍어 보시는것은 어떨런지요.? 그리고 윈도우쪽에
send() 리턴을 한번 찍어 보시는것은 어떨런지요.? 그리고 윈도우쪽에서도 recv() 리턴을 한번 찍어 보는건 어떨까요.? 구조체로 보내기 하실때는 엔디안 문제도 있지만(이경우는 아닐테구) 조금만 잘못 보내도 중간에 강제로 끊어 버리는것 같더라구요.
제 생각에는 두 함수 모두 보내고 몇바이트가 갔는지 리턴을 찍어 보시는게 빠른 방법일수도 있을거 같아요.
건강하세요.
다음의 설명이 TCP 통신의 정석을 보여줍니다.
http://sunyzero.tistory.com/167
소켓을 close하기 전에, send한 내용이 정말로
소켓을 close하기 전에, send한 내용이 정말로 수신되었는지 확실하게 할 수 있는 가장 직관적인 방법이 있습니다.
수신측에서 해당 내용을 받은 다음에 회신하게 해서, 송신측에서 이 회신을 확인한 뒤 close하는 것이죠.
사실 TCP 프로토콜 자체가 이러한 Acknowledgement 메커니즘을 포함하고 있으니 중복 투자 같은 느낌이 들긴 합니다만, 그 메커니즘이 어플리케이션에서 접근 가능한 것인지 잘 모르겠네요.
하지만 지금처럼 socket close 직전이라 synchronization이 특히 중요할 때는 해 볼 만 하겠지요.
덧. 2003년 질문이었네요. -_-;;;
Send 직 후 Close에 대한 문제 및 고찰
http://sunyzero.tistory.com/167
위 링크가 귀하께 답을 해주고 있습니다.
이는 윈도우즈나 리눅스의 OS의 문제가 아님을 아시게 됩니다.
물론 귀하의 경험상의 경험은 같은 네트워크 단에서 같은 OS에서
우연의 일치처럼 아귀가 맞을 수 있습니다.
그러나 다른 환경에서 같은 OS라고 해서 님의 경험처럼 반드시 라는 전제를
단정할 수는 없는 일 입니다.
해당 링크를 보시게 되면 최종의 Recv 후 (클라이언트 단) 해당 단에서 Close 하면
여기서는 서버에서 Recv에서 해당 Close에 대한 이벤트로서 발동하여 Recv를
멈추게 되고.. 해당 리턴 값으로 Close 여부를 아시게 됩니다.
사실 이게 권장 사항입니다.
물론 항상 100%는 아니지만 귀하의 경험이나 개발 방식에 비해서는
해당 권장 사항이 오류나 오동작을 헐씬 더 낮출 수 있을 것입니다.
Send 직 후 Close에 대한 문제 및 고찰
추신: 서버이든 클라이언트 이든 대개의 경우 일의 방식에 따라 다르지만
최종의 목표 지점이 아닌 이상 임의로 Close하지 않는 것이 권장이라 할 수 있습니다.
즉 최종 목적지가 어디 인가 그 해당 지점에서 Close 결정 권한이 결정 지을 수 밖에 없을 것이므로
최종 지인 곳에서 Close를 하고
최종 지에 아니 곳은 다음의 일이 되는 Recv 또는 Send에서 해당 Close 시글널을 받으면 에러 코드 리턴하니 해당
시그널 받은 후 자신의 자원을 Close하라는 것입니다.
예전에 외국에 다른 소스코드를 보았었는데요
아마도. 몽구스 서버'였을겁니다.
ioctlsocket()으로 바로 소켓 종료가 가능했습니다.
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms738573(v=vs.85).aspx
그리고. 윈도우에서는 이외에도. 리눅스와는 다른 많은 함수를 사용하고 있습니다.
http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=960875&ref=960875&page=1
제가 연습하던 소스도 적어봅니다.
http://blog.daum.net/knightofelf/1165
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기