여기저기 있는 소켓 프로그래밍 관련 FAQ를 모았다. 물론 유닉스 꺼만 있다.
주요 참고 사이트 1. http://www.unl.csi.cuny.edu/faqs/sock-faq/html/unix-socket-faq.html
주요 참고 사이트 2. http://www.faqs.org/faqs/unix-faq/socket/
주요 참고 사이트 3. http://wiki.kldp.org/wiki.php/CSocketFAQ
주요 참고 사이트 4. http://wiki.kldp.org/Translations/Raw_IP_FAQ-KLDP
정리한 것은 내가 필요한 내용 ㅋㅋㅋ
소켓의 접속 해제는 어떻게 판단해야하나?
정상적으로 TCP 연결이 종료되는 경우
즉 상대방이 close()나 exit을 호출한 경우 상대방 TCP가 FIN 메시지를 날린다.
이 경우 유닉스 계열에서는 recv/read 함수가 0을 반환하게 된다.
비정상적으로 TCP 연결이 종료되는 경우
(상대방 시스템이 리붓하였거나 TCP연결을 연 쓰레드가 죽은 경우 혹은 l_noff=1, l_linger=0 으로 설정하고 close()하는 경우)
상대방 TCP는 RST 메시지를 날리게 되고 이 경우 send나 recv 함수에서 ECONNRESET (connection reset by peer) 에러가 발생한다.
즉 recv 가 0을 반환하거나 send, recv가 connection reset by peer 에러를 반환하는 경우 TCP 연결이 해제 된 것으로 보고 소켓을 닫아야한다.
send, recv가 connection reset by peer 에러 이외에 다른 에러를 반환하는 경우에는 어떻게 처리해야할까?
나는 그냥 소켓 종료시키고 다시 연결했는데 올바른 방법은 찾아보질 않아서 모르겠다. 위 두 경우는 확실한 접속 종료. ^^
bind()가 실패하면 socket descriptor는 어떻게 처리해야할까?
프로그램을 종료 (exit) 하는 경우 유닉스 계열에서는 소켓 디스크립터가 알아서 close 되므로 따로 처리할 필요없다
프로그램을 종료하지 않는 경우 close로 socket descriptor를 닫아야한다.
sendto, send, write 함수는 무슨 차이가 있나?
똑같다.
send는 sendto에서 주소 값이 NULL로 되어있는 것.
write는 send에서 flag 값이 NULL로 되어있는 것.
전송 Delay를 줄이고 싶다면? TCP_NODELAY 사용법.
TCP는 네이글 알고리즘 (Nagle Algorithm)이란걸 사용한다.
네트워크를 효율적으로 사용하려고 데이터를 버퍼에 쌓아두었다가 일정량이 차면 전송하는 것이다.
물론 조금 기다려봐서 데이터가 더 이상 들어오지 않으면 그냥 전송한다.
작은 데이터를 반드시 빨리 보내야하는 경우 네이글 알고리즘을 사용하지 않도록 설정해야한다.
다음과 같이 소켓을 설정하면 네이글 알고리즘을 사용하지 않도록 할 수 있다.
int sock;
int flag = 1;
sock = open(...);
if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0)
{
printf("setsockopt error\n");
....
}
서버가 accept()하기도 전에 클라이언트의 connection() 함수가 종료됩니다.
서버에서 listen() 함수를 이용해 소켓을 listen 상태로 만들면 TCP 레이어에서 해당 소켓을 listen 하고있는 소켓의 목록에 집어넣는다.
이때 상대방이 connection() 함수를 호출하여 connection을 시도하면 TCP레이어는 해당 소켓은 listen 목록에서 connection 목록으로 옮긴다.
이때 TCP는 SYN 신호를 보내 접속이 성공적으로 이루어졌음을 알린다.
accept()는 소켓이 connection 목록에 있는지 검사하는 것이므로 accept()여부에 상관없이 상대방 connection() 함수는 성공 혹은 실패를 반환하게 된다.
connect() 함수의 에러 반환
EALREADY 에러 (에러 번호 114)
아직 이전 작업이 다 안끝난 소켓에 다른 작업을 또 지시히면 EALREADY 에러가 나온다.
EINPROGRESS 에러 (에러 번호 115)
아직 connection 작업중이라는 뜻이다.
이 에러를 보기 싫으면 blocking으로 작동하게 한다.
blocking이 싫으면 이 에러를 만났을때 select 등을 이용해서 기다린다~
connect 함수를 non blocking으로 했을때 select의 timeout
connect 함수를 non blocking으로 하고 select의 timeout시간을 무한대로 한 경우 connect 함수를 호출한 한참 뒤에 링크가 되어도 connection이 성공적으로 수행된다.
selet timeout 된경우 다시 connect 함수를 호출하면 EALREADY 에러가 발생한다. 소켓을 close하고 다시 connect해야한다.
링크가 연결되는 즉시 connection이 되도록 하고 싶으면 select timeout을 짧게 설정하고 timeout시에 소켓 close하고 다시 connect하는 방식을 사용한다.
'Network' 카테고리의 다른 글
TCP-IP 강좌 (1) | 2008.12.27 |
---|---|
IP 주소와 MAC 주소 둘 다 사용하는 이유 (0) | 2008.12.25 |
gcc 함수 동기화(synchronization) pthread_mutex_lock() (0) | 2008.08.22 |
KT, 와이브로 기술 이용한 모바일 USN 개발 (0) | 2008.07.22 |
smart dust ( 스마트 더스트) (0) | 2008.07.21 |