소켓 프로그래밍 기초 질문입니다.
글쓴이: seongwon1 / 작성시간: 목, 2004/02/19 - 4:00오후
안녕하세요?
간단한 iterative 소켓 서버와 클라이언트를 만들었는데요. 조금 이상한
점이 있어서 질문을 드립니다.
일단 서버 코드는요.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <arpa/inet.h> #include <sys/socket.h> #define MAX_BUF 1024 int main(int argc, char *argv[]){ struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sock_server; int sock_client; char message[MAX_BUF]; char message1[]="HI!!"; int clnt_addr_size; int size; if(argc != 2){ fprintf(stderr, "Usage : %s <port>\n", argv[0]); exit(1); } ///////// make socket //////////////// if((sock_server = socket(AF_INET, SOCK_STREAM, 0))== -1){ fprintf(stderr, "Fail to make socket descriptor\n"); exit(1); } //////// initialize server_addr //////// memset(message, 0, sizeof(message)); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[1])); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //////// bind with server addr ///////////// if(bind(sock_server, (struct sockaddr *)&server_addr, sizeof(server_addr))== -1){ fprintf(stderr, "Fail to bind with socket descriptor\n"); exit(1); } ////////// server ready to accept if(listen(sock_server, 5)==-1){ fprintf(stderr, "Fail to listen\n"); exit(1); } clnt_addr_size=sizeof(client_addr); while(1){ if((sock_client=accept(sock_server, (struct sockaddr *)&client_addr, &clnt_addr_size))==-1){ fprintf(stderr, "Fail to accept for client\n"); exit(1); } read(sock_client, message, sizeof(message)); message[strlen(message)] = '\0'; if(strcmp(message, "end")==0) break; printf("client input %s\n", message); write(sock_client, message1, sizeof(message1)); close(sock_client); } write(sock_client, "Bye!!", 5); close(sock_client); printf("All client had gone!!\n"); close(sock_server); return 0; }
이구요. 클라이언트 코드는
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <arpa/inet.h> #include <sys/socket.h> #define MAX_BUF 1024 int main(int argc, char *argv[]){ struct sockaddr_in client_addr; int sock_client; char message[MAX_BUF]; char message1[MAX_BUF]; int size; if(argc != 3){ fprintf(stderr, "Usage : %s <ip address>, <port>\n", argv[0]); exit(1); } ///////// make socket //////////////// if((sock_client = socket(AF_INET, SOCK_STREAM, 0))== -1){ fprintf(stderr, "Fail to make socket descriptor\n"); exit(1); } //////// initialize server_addr //////// memset(&client_addr, 0, sizeof(client_addr)); client_addr.sin_family = AF_INET; client_addr.sin_port = htons(atoi(argv[2])); client_addr.sin_addr.s_addr = inet_addr(argv[1]); printf("Enter the string to input server : "); gets(message1); if(connect(sock_client, (struct sockaddr *)&client_addr, sizeof(client_addr))== -1){ fprintf(stderr, "Fail connect to server\n"); exit(1); } write(sock_client, message1, sizeof(message1)); read(sock_client, message, sizeof(message)); message[strlen(message)] = '\0'; printf("Server said %s\n", message); close(sock_client); return 0; }
위와 같습니다.
서버가 argument로 포트 번호를 받아서 구동을 시작하면, 클라이언트가
argument로 ip와 port 번호를 받아서 접속을 하고
특정 문자열을 입력하면 서버는 그냥 "HI!!"라고 결과를 리턴해주는
왕초보 유치 서버인데요. :oops: 기본적인 작동은 매우 정상적으로
잘 됩니다만, 클라이언트에서 "end"를 입력했을 경우, 즉 코드를 보시면
아시겠지만 "end" 입력시 서버가 종료되게 되는데요.
이렇게 해서 서버를 종료하고 나면 다시 서버를 실행했을 경우
"Fail to bind with socket descriptor" 라는 에러를 내면서 서버가
시작이 안됩니다. 아시다시피 bind()에서 실패를 했다는 뜻인데요.
왜 실패를 하는 건지 잘 이해가 안됩니다. 그래서 이상하다..
다시 컴파일 하고 해볼까? 하고 컴파일하고 다시 실행했더니 다시
실행이 되네요. -_-;;
뭐가 문제인건지....고수님들의 도움 부탁드립니다.
그럼 모두모두 좋은 하루 보내시구요.
수고하시길...
Forums:
setsockopt()에 SO_REUSEADDR 을 사용해 보세요..
setsockopt()에 SO_REUSEADDR 을 사용해 보세요..
비슷한 내용의 글이 많답니다.. 검색 한번 해 보시길..
TIME_WAIT에 대해서 찾아 보세요.
TIME_WAIT에 대해서 찾아 보세요.
산넘어 산
아 일정 시간이 지나니 다시 되네요.
컴파일을 다시 하면 되거나 하는게 아니라 일정 시간이 지나면 다시
되는 거였습니다.
IPC의 FIFO를 배우면서 파이프가 일정시간동안은 사라지지 않는다는
내용을 읽은 것 같은데 이것도 그거랑 비슷한지도 모르겠네요.
조금 더 찾아봐야 할 듯.
답변 감사드립니다.
perror
참고로 에러 처리할 때는 perror()를 사용하십시요.
그러면 정확한 에러메시지를 확인 할 수 있습니다.
예를 들면,
이 부분을
라고 하시면 정확한 에러의 이유가 나올 것입니다.
perror()의 인자는 아무거나 어디서 에러가 발생 했는지 알 수 있는 문자열이면
됩니다. 위의 예에선 socket() 이 어떤 에러를 내는지 알기 위함이므로 인자로
socket()을 넘긴 것입니다. 뭐 "소켓에서에러" 라고 한글로 해도 되겠지요.
SOrCErEr
dudungsil 님이 말씀하신대로 TIME_WAIT 상태 때문에 그렇습
dudungsil 님이 말씀하신대로 TIME_WAIT 상태 때문에 그렇습니다.
이 상태는 TCP에서 먼저 close를 호출한 쪽에서 거치는 상태입니다.
TCP에서 이러한 상태를 두는 이유는 (스티븐 아저씨 책에 있는 내용)
1. 신뢰성 있는 TCP의 양방향 연결종료 보장
2. 네트워크에서 오래된 복사본 세그먼트를 소멸하도록 한다.
입니다.
쉽게 이해 하시려면 TCP 상태전이와 TCP 연결종료에 대해서 보시면 될 겁니다.
나를 죽이지 않는 모든 것은 나를 강하게 할 뿐이다.
댓글 달기