소켓 통신에서...
글쓴이: 하하 / 작성시간: 화, 2003/11/25 - 10:31오전
소켓 통신 중 .. 연결하려는 호스트까지 네트워크 병목현상이 있어
어느 정도(3초~5초)의 delay time 후 connect이 확립됩니다.
그럴때... 호스트로 부터 recv를 할려 하면 아래와 같이 구현해보면
while ( hdsz > recv_total ) { recv_byte = recv(sock, header + recv_total, hdsz - recv_total, 0); recv_total = recv_total + recv_byte; if ( hdsz > recv_total ) { if (cnt > 5) break; else { cnt++; sleep(5); } printf("*****received byte %d , total %d\n", recv_byte, recv_total); } }
메세지를 다 받지 못하였을 때 5초후 recv를 다시 시도 하게끔
구현 하였습니다.
헌데 이럴 경우 5초식 5번 recv를 시도 하여도 한 byte도 받지 못하고
0, 0, 0, 0, 0 byte만을 받다가 끝나고 맘니다.
그런데 이상한건..
sleep(5); recv_total = recv(sock, header, hdsz, 0);
이런식으로 최초 recv하기도 전에 5초간 쉬고.. recv를 하면 100% 데이터를
받아 온다는 겁니다.
한번의 실패도 없이요........
제가 못 보는 다른 문제가 있는건지요?
조언 부탁드립니다.....
아 .. 그리고 위와 같이 데이터를 못받았을때 위와 같이 sleep을 주는 게
일반적인 방법인지도 알고 싶습니다.
Forums:
안녕하세요.. 질문만 보아서는 약간 자료가 부족하나..제가 아는한
안녕하세요.. 질문만 보아서는 약간 자료가 부족하나..
제가 아는한도에서 이야기를 하도록 하겠습니다.
네트웍이 느려서 recv를 한경우 timeout 시간이 초과되면
데이타를 받지 못하고 리턴되는경우가 잇습니다. 또한 논블러킹인
경우에도 그렇죠. 그리고 sleep는 일반적으로 사용하지 않습니다..
특수한경우빼고는요.. 고로 소켓관련 이벤트 처리를 해주셔야할것같습니다.
소켓의 시간초과 예외나 또는 누군가 한번보낸다고 꼭 한번 recv해서
처리되지 않는경우도 있씁니다. 그리고 몇몇예외가 있지요..
그런것을 기본적으로 감안하시면 되실것 같습니다.
결론 sleep을 안써도 된다.~ -_-!
언제나 제가쓰는글은 잡설같군요..
' 형식이 내용을 규정한다. '
논블러킹으로 구현하신거 맞으신가요?connect하는데 3~5초가
논블러킹으로 구현하신거 맞으신가요?
connect하는데 3~5초가 걸린다는게 믿어지지는 않지만
그렇다고 하니 어쩔 수 없고....
말씀하신 상황과 코드만 가지고는 납득이 안 가는 부분이 너무 많지만, 많은 경우의
수와 가능성을 고려해 볼때..
요렇게 해 보면 되지 안을까 싶습니다.
그리고, 일반적으로 sleep() 사용하지는 않지요. 논블러킹에서 recv()쓸때는 select()와 많이 조합해서 씁니다.
http://doc.kldp.org/Translations/html/Socket_Programming-KLDP/Socket_Programming-KLDP.html
.
select() 가 제가 보기에도 가장 나을거 같네요...sleep(
select() 가 제가 보기에도 가장 나을거 같네요...
sleep()을 사용한다는건 꽁수 같구요^^
select()는 sleep()의 기능도 하면서 일정한 시간동안 계속 잠들어 있는게 아니라...
데이타가 들어오면 바로 깨어나서 자료 송/수신을 하니 sleep() 보다 나을거 같군요.
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
select를 사용하세요
select를 사용하세요
현상을보니 nonblocking 모드로 되어 있어신것 같습니다.
select를 이용해서
int is_rxsocket_ready(int socket , int timeoutsec, int usec);
이라는 함수를 하나 만드시고
이런식으로 처리하시면 time out 만큼 기다리는게 아니라
timeout 이전이라도 data가 들어오면 처리를 하게 됩니다.
socket은 nonblocking 모드로 설정되어야 겠죠.
파이팅 하세요
recv 받는 루틴은 아래와 같이 구성되어 있습니다.주석으로 막은
recv 받는 루틴은 아래와 같이 구성되어 있습니다.
주석으로 막은 부분은 위에서 설명한 바대로 0 byte 만을 루프를
돌면서 받고 끝내 실패...
요런식의 꽁수를 써서 recv를 해보면 그재야 데이터를 받을 수 있습니다.
sock은 블럭킹 모드 입니다.
저도 하도 이상하길래.. 아래와 같이 sleep을 주어 delay 타임을 준
것이구요.. sleep(5) 이하 그러니깐 sleep(4) 이하를 주면 역시 0
byte 만을 받습니다........
“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”
[quote]while ( hdsz > recv_total )
이처럼 recv를 하고 sleep(5)를 주어도 마찬가지로 0 byte만을 반복적으로
받습니다..
“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”
Re: 소켓 통신에서...
이 병목 현상의 원인은 거의 대부분 name resolving입니다.
x=foo(y)가 성립되지 않는 세계에 오신걸 환영합니다.
There is no spoon. Neo from the Matrix 1999.
댓글 달기