인터넷과 소켓프로그래밍

TCP 에코 서버 (계속)

kang057 2024. 7. 28. 09:41
/* Echo Clinet가 TCP에게 접속설정 요청(connect() 수행)
 * 클라이언트의 TCP는 접속설정요청 패킷을 서버측 TCP에게 전송
 * Echo Server측 TCP는 접속설정 요청이 도착하면
 * Echo Server가 bing()를 수행하였는 지 확인하고
 * ACK를 클라이언트 TCP에게 전달하고 기다림
 * Echo Client측 TCP는 서버측 TCP가 전송한 ACK에 대한 ACK를 전송
 * Echo Server측 TCP는 접속이 완료되었음을 Echo Server에게 알림
 * 이것을 TCP에게 지시하는 함수 : accept()
 */
 
 do {
 	memeset(&cli_addr, 0, clilen);
        
        /*
         * 서버는 소켓 sockfd에 새로운 섭속이 설정됨을 기다림
         * 새로운 접속이 설정되면 새로운 소켓 magsock이 생성됨
         * masock : 기존 sockfd의 내용을 그대로 복제함
         * 클라이언트 정보는 cli_addr에 자도아으로 저장됨
         */
         
         printf("server: waiting.....\n");
         magsock = accept(sockfd, (struct sockaddr *)&cli_addr, (int *)&clilen);
                   
         printf("New Accept Socket : %d\n", magsock);

 

accept() - 새로운 접속완료 시 알림 요청

 

● getsockname(), getpeername() - 소켓 정보 구하기

=>  소켓의 로컬 및 원격 주소 정보를 구하는 데 사용한다. 각각의 함수는 소켓을 통해 얻을 수 있는 정보를 기반으로 네트워크 프로그래밍에서 중요한 역할을 한다. 

 

○ getsockname() : 현재 소켓에 바인딩된 로컬 주소를 가져온다.

int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

- sockfd : 소켓 파일 디스크립터

- addr : 소켓의 로컬 주소를 저장할 구조체

- addlen : 주소 구조체의 길이

 

○ getpeername() : 소켓에 연결된 원격 주소를 가져온다.

int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

- sockfd : 소켓 파일 디스크립터

- addr : 소켓의 로컬 주소를 저장할 구조체

- addlen : 주소 구조체의 길이

if (magsock == -1) {
	printf("server: accept error\n");
    	exit(2);
}

else {
    /*
     * 클라이언트 소켓 정보 출력
     * inet_ntoa : 숫자로된 IP주소를 Ascii로 출력
     */
     
     printf("클라이언트 연결됨 %s\n", inet_ntoa(cli_addr.sin_addr));
     
     do {
	    memset(buf, 0, sizeof(buf));
            /* TCP에게 데이터를 수신 요청 */
            if (nbyte = read(magsock, buf, 1024)) == -1) {
		printf("server: READ error\n");
                exit(2);
            }
            
            else {
		printf("수신 : %s\n", buf);
                
                /* 수신한 데이터를 Echo TCP에게 데이터 전송 요청 */
                if (write(magsock, buf, nbyte_ == -1) {
                	printf("Echo Server : idea transfer error\n");
                    exit(2);
               }
    } while (nbyte != 0);
} // if (magsock != -1)

 

read() - 소켓에서 데이터 읽기(수신)

write() - 소켓에 데이터 쓰기(송신)

 

=> 운영체제는 수신축으로 부터 데이터를 읽으며 응용 프로세스가 read()/receive() 시스템 콜을 호출할 때 까지 저장하고 있다가 read()/receive()를 호출하면 최대 원하는 양만큼 없으면 block 됨

 

close() - 접속 종료 요청

 

 

● TCP 서버 프로그램 정리

interative, TCP 서버

socket() : 소켓 개설

bind() : 소켓 번호와 소켓주소의 결합

listen() : 동시 접속 설정 요청/갯수 setting

accept() : 연결 수락, 연결 완료시 통보 요청

read(), 서비스처리, write : 클라이언트의 요구를 처리한 후 결과 전송

finished? } while(TRUE);

close();