본문 바로가기

UNIX_LINUX_C_C++

bind error : Address already in use

아래는 joinc.co.kr에 있는 소스를 약간 수정하여 만든 echo서버이다.

실행시 포트를 정하게 되어 있는데, 원소스를 그대로 사용할 경우

한번 실행 후 종료하고, 다시 같은 포트로 실행할 경우

bind error : Address already in use

에러가 발생하게 된다. 아직 운영체제에서 프로그램에서 사용한 포트를 수거하지 못했기 때문이다.

보통 10분 정도 있으면 반환하게 된다.

on = 1;
setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

이렇게 SO_REUSEADDR 옵션을 켜주면 이런 문제를 해결할 수 있다.

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char **argv)
{
int server_sockfd, client_sockfd;
int state, client_len;
int chk;
int on;

struct sockaddr_in clientaddr, serveraddr;

char buf[255];

if (argc != 2)
{
printf("Usage : ./echo [port]\n");
printf("예 : ./echo 4444\n");
exit(0);
}

state = 0;

// 주소 파일을 읽어들인다.
client_len = sizeof(clientaddr);


// internet 기반의 소켓 생성 (INET)
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket error : ");
exit(0);
}

on = 1;
setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(atoi(argv[1]));

state = bind(server_sockfd , (struct sockaddr *)&serveraddr,
sizeof(serveraddr));

if (state == -1)
{
perror("bind error : ");
exit(0);
}

state = listen(server_sockfd, 5);
if (state == -1)
{
perror("listen error : ");
exit(0);
}

chk = 0;
while(!chk)
{
client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
&client_len);
if (client_sockfd == -1)
{
perror("Accept error : ");
exit(0);
}

printf("connect!\n");
while(1)
{
memset(buf, 0, 255);
if (read(client_sockfd, buf, 255) <= 0)
{
close(client_sockfd);
break;
}

if (strncmp(buf, "quit",4) == 0)
{
write(client_sockfd, "bye bye", 8);
printf("bye\n");
close(client_sockfd);
break;
}

if (strncmp(buf, "servquit", 8) == 0)
{

write(client_sockfd, "bye bye", 8);
chk = 1;
printf("quit\n");
close(client_sockfd);
break;
}


write(client_sockfd, buf, 255);
printf("%s\n", buf);
}
}
printf("quit\n");
close(server_sockfd);

return 0;
}