- 09-2 : SO_REUSEADDR
- 주소할당 에러(Binding Error)발생
- SO_REUSEADDR 옵션에 대한 이해에 앞서 Time-Wait 상태를 먼저 이해해야한다.
- 이를 위한 예제 reuseadr_eserver.c 를 보자
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define TRUE 1
#define FALSE 0
void error_handling(const char *message);
int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
char message[30];
int option, str_len;
socklen_t optlen, clnt_adr_sz;
struct sockaddr_in serv_adr, clnt_adr;
if(argc != 2){
printf("Usage :%s <port>\n", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
error_handling("socket() error");
/*
optlen = sizeof(option);
option = TRUE;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, (void*)&option, oplen);
*/
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)))
error_handling("bind() error");
if(listen(serv_sock, 5) == -1)
error_handling("listen() error");
clnt_adr_sz = sizeof(clnt_adr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
while((str_len = read(clnt_sock, message, sizeof(message))) != 0)
{
write(clnt_sock, message, str_len);
write(1, message, str_len);
}
close(clnt_sock);
close(serv_sock);
return 0;
}
void error_handling(const char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
- 위 예제는 지금까지 몇 차례 구현해 온 에코 서버 프로그램이다 따라서 Chapter04에서 소개한 에코 클라이언트와 함께 실행하면 된다.
- 클라이언트 콘솔에서 q메세지를 입력하거나 CTRL+C를 입력해서 프로그램을 종료시켜보면 Four-way handshaking 과정을 거치며 서버측으로 FIN메세지가 전달된다. 프로그램을 강제종료할 경우에도 운영체제가 파일 및 소켓을 모두 닫아주는데 이과정에서 close함수를 호출한 것과 마찬가지로 서버측으로 FIN메세지가 전달된다.
- 위 상황은 별다른 현상은 관찰되지 않는것으로 느껴질수있다 그렇다 클라이언트가 먼저 연결종료를 요청하는 경우는 매우 일반 적인 상황이기 때문에 별다른 일이 발생할것이없다. 서버의 재실행도 문제되지 않는다
- 그러나 서버와 클라이언트가 연결된 상태에서 서버측 콘솔에서 CTRL+C를 입력해서 서버 프로그램을 강제종료한다면 서버가클라이언트측으로 먼저 FIN메세지를 전달하는 상황이 된다.
- 위의 상황이 되면 동일한 PORT번호를 기준으로 서버를 재실행하면 bind()error라는 메시지가 출력될 뿐 서버는 실행되지 않고 3분정도가 지나서야 재실행시 정상적인 실행이된다 두방식의 유일한 차이점은 FIN메세지를 누가먼저 전송했는지에 있다.
'책 > 윤성우 TCPIP' 카테고리의 다른 글
09-2 : SO_REUSEADDR (3) (0) | 2020.12.14 |
---|---|
09-2 : SO_REUSEADDR (2) (0) | 2020.12.13 |
09-1 소켓의 옵션과 입출력 버퍼의 크기 (2) (0) | 2020.12.11 |
09-1 소켓의 옵션과 입출력 버퍼의 크기 (0) | 2020.12.10 |
chapter 08 -2 , ip주소와 도메인 이름 사이의 변환 (3) (0) | 2020.12.09 |