socket질문입니다.
글쓴이: kang0203 / 작성시간: 금, 2003/04/04 - 8:35오후
---- client ------ #include "evermode.h" #define PORT 7894 #define MAXSIZE 1024 int main(int argc,char *argv[]) { int servfd,nbyte; struct sockaddr_in server; char buf[MAXSIZE]; if((servfd = socket(AF_INET,SOCK_STREAM,0)) == -1) { perror("Can not open socket"); exit(-1); } bzero((char *)&server,sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = inet_addr(argv[1]); if(connect(servfd,(struct sockaddr *)&server,sizeof(server)) < 0) { perror("Can not connect"); exit(-1); } if((send(servfd,"Hello, world!\n",14,0)) < 0 ) { perror("error recv"); exit(-1); } close(servfd); } ---- server ---- #include "evermode.h" #define PORT 7894 #define MAXSIZE 1024 #define WQUEUE 5 int main(int argc,char *argv[]) { int servfd,clifd,clilen,nbyte; struct sockaddr_in server,client; char buf[MAXSIZE]; pid_t pid; if((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("Can not open socket"); exit(-1); } bzero((char *)&server,sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = INADDR_ANY; if(bind(servfd,(struct sockaddr *)&server,sizeof(server)) < 0) { perror("error bind"); exit(-1); } listen(servfd,WQUEUE); while(1) { if((clifd = accept(servfd,(struct sockaddr *)&client,&clilen)) < 0) { perror("error accpet"); exit(-1); } printf("accept client\n"); if((pid = fork()) != 0) { close(clifd); } else if(pid == 0) { close(servfd); if((nbyte = recv(clifd,buf,MAXSIZE,0)) < 0) { perror("error recv"); exit(-1); } buf[nbyte] = '\0'; printf("buf = %s\n",buf); close(clifd); } } }
서버와 클라이언트에서 한 문자열을 주고 받는 프로그램입니다.
하지만 한 클라이언트가 문자열을 보내면 보낸 문자열이 출력되고 바로 밑에 error accept : Bad number ...어쩌구 이런 에러가 납니다.
제 생각에는 TCP/ip 가 접속을 끊면서 뭔가를 서버에 보내는것 같은데여..
뭐가 문제인지 도저히 알수가 없어여...
도와주세요... 헬프미~!~~~
Forums:
---- server ----1. Add Check For lis
---- server ----
1. Add Check For listen
2. Use "server" as socket id for accept
3. You can get useful source code by using google or FAQ
- I'm NewB too.
^^
그 에러메시지는 server program의 parent가 아니라 child가 내는 것입니다.
child 프로세스는 현재 작업을 처리하면 exit() 해서 종료를 해 주어야 하는데, 현재는 child가 hello 를 찍고도 종료를 하지않고 있습니다. 그러다 보니 클라이언트도 다시 accept()문으로 들어가게 되는데, 이미 클라이언트는 servfd를 닫아서 위와 같은 오류가 발생한 겁니다.
따라서 pid == 0 인 경우에는 처리가 끝나면 exit()하도록 코드를 추가해 주시면 되겠습니다.
acccept()의 세번째 인자인 addrlen 은 value-result 이므로 addrlen = sizeof(client) 로 매번 accept() 수행전에 넣어주셔야 안전합니다. 맨 처음 한번만 초기화해도 거의 문제는 안 생기겠지만 보장은 못합니다.
ycode님께서 accept()의 두번째 파라메터로 server를 넣으라고 하셨는데, 그쪽은 변수이름상 client를 넣는게 맞을 듯 합니다. 해당 소켓으로 연결한 클라이언트의 주소를 돌려주는 것이기 때문입니다.
클라이언트 주소에 관심이 없으시면 두번째 param을 NULL로 하시거나 addr길이를 0으로 하시면 됩니다.
댓글 달기