Download presentation
Presentation is loading. Please wait.
Published byVerawati Hartanto Modified 6년 전
1
인공지능실험실 석사 2학기 이희재 lhuijae@ai.hannam.ac.kr
TCP/IP Socket Programming… 제 7장 소켓 연결의 우아한 종료 인공지능실험실 석사 2학기 이희재
2
목차 소켓 연결 종료의 문제점 우아한 소켓의 연결 종료 윈도우 기반으로 구현하기
3
소켓 연결 종료의 문제점 close 함수의 호출 연결의 완전 종료 데이터 송•수신을 할 수 없음
호스트 A가 마지막 패킷을 전송한 후 close 함수를 호출하면 호스트 B가 전송하는 마지막 응답 패킷을 받지 못 할 수도 있음 shutdown 함수(half close)를 사용함으로서 close 함수의 문제를 해결
4
소켓 연결 종료의 문제점 소켓과 스트림(Stream) 두 호스트가 소켓을 통해 연결된 상태를 스트림이 생성되었다고 표현
두 호스트가 소켓을 통하여 연결되면 입력 스트림과 출력 스트림이 생성됨 한 호스트의 입력은 다른 호스트의 출력 스트림에 연결 한 호스트의 출력은 다른 호스트의 입력 스트립에 연결 close 함수 호출 : 입•출력 스트림 모두 종료 shutdown 함수 호출 : 종료할 스크림 선택 가능
5
우아한 소켓의 연결 종료 스트림 half-close 기능의 함수 s : 종료하고자 하는 소켓의 파일 디스크립터
how : 종료 모드 SHUT_RD(입력), SHUT_WR(출력), SHUT_RDWR(입•출력) #include <sys/socket.h> int shutdown (int s, int how) 리턴값 : 성공 시 0, 실패 시 -1
6
우아한 소켓의 연결 종료 half-close 기능이 필요한 경우의 예제 파일 전송 프로그램 서버 클라이언트가 서버에 연결
서버는 클라이언트에게 파일을 전송한다. 클라이언트는 서버로부터 파일을 수신한 후 “Thank you”메시지 전송. 클라이언트는 EOF를 수신해야 “Thank you”메시지를 전송. close, shutdown 함수 모두 EOF를 전송하지만 서버는 shutdown 함수를 호출해야 클라이언트로부터 “Thank you”메시지를 받을 수 있다. 서버 클라이언트 연결요청 파일전송 EOF 전송 Thank you
7
우아한 소켓의 연결 종료 파일 전송 서버 … int serv_sd; int clnt_sd; int fd;
char buf[BUFSIZE]; struct sockaddr_in serv_addr; struct sockaddr_in clnt_addr; int clnt_addr_size; int len; fd = open("file_server.c", O_RDONLY); //파일오픈 serv_sd = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(atoi(argv[1])); bind(serv_sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); listen(serv_sd, 5); clnt_addr_size = sizeof(clnt_addr); clnt_sd = accept(serv_sd, (struct sockaddr *)&clnt_addr, &clnt_addr_size); // 파일의 내용을 클라이언트에게 전송 while ((len = read(fd, buf, BUFSIZE)) != 0) { write(clnt_sd, buf, len); } // 파일전송을 마치고 출력스트림을 닫는다. if (shutdown(clnt_sd, SHUT_WR) == -1) { error_handling("shutdown() error"); // 클라이언트로부터 “Thank you”메시지 수신 len = read(clnt_sd, buf, BUFSIZE); write(1, buf, len); // 표준 출력(모니터)으로 출력 close(fd); close(clnt_sd); …
8
우아한 소켓의 연결 종료 파일 수신 클라이언트 … int fd; int sd; char buf[BUFSIZE];
struct sockaddr_in serv_addr; int len; // 서버로부터 수신한 파일의 내용을 저장할 파일 fd = open("receive.dat", O_WRONLY | O_CREAT | O_TRUNC); sd = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); connect(sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); while ((len = read(sd, buf, BUFSIZE)) != 0) { write(fd, buf, len); } // 파일수신이 끝나면 서버에 “Thank you”로 응답 write(sd, "Thank you\n", 10); close(fd); close(sd); …
9
우아한 소켓의 연결 종료 실행 결과
10
윈도우 기반으로 구현하기 윈도우 기반의 half-close 함수 s : 소켓핸들 how : 종료 모드
SD_RECEIVE(입력), SD_SEND(출력), SD_BOTH(입•출력) #include <winsock2.h> int shutdown (SOCKET s, int how) 리턴값 : 성공 시 0, 실패 시 SOCKET_ERROR
11
윈도우 기반으로 구현하기 윈도우 기반의 파일 전송 서버 … // 클라이언트에게 보내줄 파일 오픈
fp = fopen("file_server_win.c", "r"); if (fp == NULL) ErrorHandling("File open error!"); hServSock = socket(PF_INET, SOCK_STREAM, 0); hClntSock = accept(hServSock, (SOCKADDR *)&clntAddr, &clntAddrSize); // 클라이언트가 연결하면 파일의 내용을 읽어서 전송 while (1) { len = fread(buf, sizeof(char), BUFSIZE, fp); send(hClntSock, buf, len, 0); if (feof(fp)) break; } … // 파일 전송이 끝나면 소켓의 출력스트림을 닫음 if (shutdown(hClntSock, SD_SEND) == SOCKET_ERROR) ErrorHandling("shutdown() error!"); //클라이언트로부터 “Thank you” 메시지 수신 및 출력 len = recv(hClntSock, buf, BUFSIZE-1, 0); buf[len] = 0; fputs(buf, stdout); fclose(fp); closesocket(hClntSock); WSACleanup();
12
윈도우 기반으로 구현하기 윈도우 기반의 파일 수신 클라이언트 … // 서버로부터 수신한 데이터를 저장할 파일
fp = fopen("receive.dat", "w"); if (fp == NULL) ErrorHandling("File open error!"); hSocket = socket(PF_INET, SOCK_STREAM, 0); // 서버에 연결 if (connect(hSocket, (struct sockaddr *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) ErrorHandling("connect() error!"); … // 서버로부터 데이터를 수신하여 파일에 저장 while((len = recv(hSocket, buf, BUFSIZE, 0)) != 0) { fwrite(buf, sizeof(char), len, fp); } // 파일 수신이 끝나면 “Thank you” 메시지 전송 send(hSocket, "Thank you\n", 10, 0); fclose(fp); closesocket(hSocket); WSACleanup();
13
윈도우 기반으로 구현하기 실행결과
14
참고문헌 “UNIX Network Programming”, W.Richard Stevens
“TCP/IP 소켓 프로그래밍”, 윤성우 저
15
Q & A
Similar presentations