최말짱 블로그

ch12 소켓을 이용한 네트워크 프로그래밍 / 연습문제 12장 본문

컴퓨터통신

ch12 소켓을 이용한 네트워크 프로그래밍 / 연습문제 12장

최말짱 2022. 12. 12. 05:02
728x90

 

 

 

 

 


 

1. 소켓에 이름을 부여하는 방법은 프로토콜 종류에 따라 다양하다. 프로그래밍 환경에서는 주로 두 개의 주세 체계가 사용된다. 즉, 호스트 내부에서 실행되는 프로세스 사이의 통신을 지원하는 () 와 서로 다른 호스트에서 실행되는 프로세스 사이의 통신을 지원하는 ()가 있다.

-> 유닉스 주소 체계, 인터넷 주소 체계 

 

2. 인터넷 주소 체계에서 사용되는 구조체인 struct ()의 ()필드에는 AF_INET이 지정되어야 한다. 또한 소켓의 주소 역할을 하는 호스트의 IP 주소와 포트번호는 각각 ()필드와 ()에 보관된다.

-> sockaddr_in, sin_family, sin_addr, sin_port

 

3. 아래 프로그램은 인터넷 주소 체계를 지원하는 변수 addr을 선언하고, 두 번째 줄에서 이 변수에 주소 값을 초기화하였다. 이후 bind() 시스템 콜에서 이 변수를 사용할 때는 문법적인 이유로 통합 주소 체계로 형 변환하고 있음을 알 수 있다.

struct sockaddr_in addr;
…. /* addr 변수가 주소 값을 지정한다고 가정 */
bind(sock,(①)&addr, sizeof(addr));

-> struct sockaddr *

 

4. 소켓의 유형 중에서 ()은 연결형 서비스를 제공하고, ()은 비연결형 서비스를 제공한다. 일반적인 응용 환경에서 자주 사용되지는 않지만 SOCK_RAW 유형은 IP 프로토콜을 직접 사용하는 경우를 위해 정의되었다.

-> SOCK_STREAM, SOCK_DGRAM

 

5. 운영체제에서 구현되는 전송 계층 프로토콜 TCP와 UDP를 사용하려면 소켓 시스템 콜이라는 라이브러리 함수를 이용해야 한다. 일반적으로 소켓은 ()라는 용어로 호칭되면, 소켓 주소는 ()라고도 부른다.

-> 포트, 포트 번호 

 

6. 아래와 같이 소켓함수를 이용하여 소켓을 생성할 수 있다. 첫 번째 줄의 경우는 인터넷 프로토콜인 ()용 소켓이 할당되고, 두 번째 줄의 경우는 ()용 소켓이 할당된다.

sd = socket(AF_INET, SOCK_STREAM, 0);
sd = socket(AF_INET, SOCK_DGRAM, 0);

-> TCP, UDP

 

7. 소켓 관련 함수들 중에서 ()은 소켓에서 대기할 수 있는 클라이언트의 연결 요청 개수를 지정하고, ()는 클라이언트의 연결 요청을 받아주는 역할을 한다. 이떄, 클라이언트의 연결 요청은 () 함수에 의해 이루어진다.

-> listen, accept, connect 

 

8. 일반적으로 연결형 소켓을 이용하는 경우에 데이터 송신은 () 함수에 의하여 이루어지고, 데이터 수신은 ()함수에 의하여 이루어진다. 비연결형 서비스의 경우는 () 함수가 데이터를 송신하고, ()함수가 데이터를 수신한다.

->send, recv, sendto, recvfrom

 

9. 인터넷을 활용하는 상용 프로그램이 여러 컴퓨터에서 실행되는 경우, 각 실행 파일에 개별 서버 호스트의 IP 주소를 지정하여 컴파일하기는 현실적으로 불가능하다. 이와 같은 상황을 고려해 ()라는 호스트 주소 표기 방법을 제공한다. 이는 프로그램이 실행되는 로컬 호스트 자체를 의미하기 때문에 프로그램이 실행되는 호스트의 ()로 자동 대체된다.

-> INADDR_ANY, IP주소 

 

10. 서버-클라이언트 모델에서 서버 프로세스는 다수의 클라이언트에 공개되는 ()로 자신의 소켓 주소를 설정한 후에, 클라이언트의 연결 요청에 대기한다. ()의 주소는 서버 호스트의 ()와 ()의 조합으로 구성되며, 인터넷 환경에서 임의의 호스트에서 실행되는 프로세스의 디스크립터 역할을 한다.

-> Well-known 포트, IP주소, 포트번호 

 

11. 소켓 주소 체계에 대한 설명으로 올바른 것을 모두 고르시오

① AF_UNIX로 표시되는 유닉스 주소 체계는 한 호스트 내부에서 실행되는 프로세스 사이의 통신을 지원한다.
② AF_INET으로 표시되는 인터넷 주소 체계는 서로 다른 호스트에서 실행되는 프로세스 사이의 통신을 지원한다.
③ 인터넷 주소 체계를 지원하는 sockaddr_un 구조체는 32비트의 IP주소와 16비트의 포트 번호를 저장할 수 있다.
④ 통합 주소 체계인 sockaddr 구조체는 단순히 프로그래밍 환경에서의 문법적인 측면을 고려하여 정의된 것이다.
⑤ sockaddr 구조체의 sa_family 필드값을 해석하면 어느 주소 체계를 사용하는지 판단할 수 있다.

 

-> 3. 인터넷 주소 체계를 지원하는 sockaddr_in 구조체는 32비트의 IP주소와 16비트의 포트 번호를 저장할 수 있다.

 

12. 소켓 주소 체계를 지원하는 구조체에 대한 설명으로 올바른 것을 모두 고르시오

① struct sockaddr_in 구조체는 인터넷 주소 체계를 지원한다.
② struct sockaddr_in 구조체의 sin_port 필드에는 포트 번호를 저장한다.
③ struct sockaddr_in 구조체의 sin_addr 필드에는 IP 주소를 저장한다.
④ struct sockaddr_un 구조체는 유닉스 주소 체계를 지원한다.
⑤ struct sockaddr 구조체는 공통 주소 체계를 지원한다.

 

->1,2,3,4,5

 

13. 소켓 함수의 개요에 대한 설명으로 올바른 것을 모두 고르시오

① 
② 
③ 
④ 
⑤ 

 

-> 

socket() 함수는 매개변수로 지정된 유형에 따라 소켓을 생성한다. 프로세스는 이 소켓을 사용하여 다른 프로세스와 통신할 수 있다.

bind() 함수는 소켓에 주소를 부여하는 기능을 수행한다.

connect() 함수는 클라이언트가 서버와 연결을 시도할 때 실행된다.

 

14. 소켓 함수에 대한 상세 설명으로 잘못된 것을 모두 고르시오

① socket() 함수는 매개변수로 지정된 유형에 따라 소켓을 생성한다. 프로세스는 이 소켓을 사용하여 다른 프로세스와 통신할 수 있다.
② bind() 함수는 소켓에 주소를 부여하는 기능을 수행한다.
③ accept() 함수는 보통 서버 프로그램에서 실행되며, 클라이언트의 연결 요구가 들어올 때 까지 대기한다. listen() 함수에서 대기 중이던 서버는 클라이언트의 연결 요구가 들어오면 accept() 함수가 이를 처리한다.
connect() 함수는 클라이언트가 서버와 연결을 시도할 때 실행된다.

⑤ send()와 recv()는 데이터를 보내고 받는 기능을 수행하는데, 주로 비연결형 서비스에서 사용된다.

 

-> 3,5

-> 3. accept() 함수는 보통 서버 프로그램에서 실행되며, 클라이언트의 연결 요구가 들어올 때 까지 대기한다. accept() 함수에서 대기 중이던 서버는 클라이언트의 연결 요구가 들어오면 accept() 함수가 이를 처리한다.

-> 5. send()와 recv()는 데이터를 보내고 받는 기능을 수행하는데, 주로 연결형 서비스에서 사용된다.

 

15. 소켓을 이용한 네트워크 프로그래밍에 대한 설명으로 올바른 것을 모두 고르시오

① 소켓은 네트워크 통신을 위한 클라이언트와 서버 프로그램의 교신점이라 할 수 있다.
② 서버 프로세스는 소켓에 포트 번호를 부여하는데, 이 번호는 인터넷에서 유일하다.
③ 일반적으로 클라이언트와 서버의 동작 과정에서 클라이언트가 먼저 연결 요청을 하고, 그에 따라 서버가 대기 상태에 진입하여 연결이 설정된다.
④ 대부분의 인터넷 서비스는 임의의 클라이언트에 대한 서비스가 종료되어도 서버는 종료되지 않고 무한 반복하여 서비스를 진행한다.
⑤ 일반적으로 데이터를 송수신하는 과정에서 연결형 서비스는 send(), recv()함수를 사용하고, 비연결형 서비스는 sendto(), recvfrom() 함수를 사용한다.

 

-> 1,4,5

-> 2. 소켓과 포트 번호는 인터넷에서 유일하지 않다.

-> 3. 일반적으로 서버가 대기상태에 먼저 있고(accept) 클라이언트가 연결요청(connect)하면 연결된다.

 

16. TCP를 이용한 클라이언트와 서버의 통신 절차에 대한 설명으로 잘못된 것을 모두 고르시오.

① 클라이언트와 서버는 둘 다 가장 먼저 소켓을 생성해야 한다. 
② 클라이언트는 생성된 소켓에 주소 부여 절차를 수행하지만, 서버는 이 절차를 생략할 수 있다.
둘을 연결하려면 서버의 accept() 함수와 클라이언트의 connect() 함수를 결합해야 한다.

④ 클라이언트와 서버는 서로 양방향 통신이 가능하므로 데이터 송신과 수신을 모두 할 수 있다.
⑤ 가장 마지막 절차는 소켓을 닫는 과정인데, 프로그래머가 생략해도 시스템에서 자동으로 실행해준다.

 

-> 2

 

17. 소켓 주소 표기와 관련해 공통의 통합 주소 체계가 필요한 이유를 설명하시오

 소켓 주소는 소켓 시스템 콜을 통해 사용되는데, 의미는 같으나 형식이 다른 구조체를 함수 매개변수 하나로 수용하는 것은 불가능하기 때문에, 여러 소켓 구조체를 통합해 일반 구조체 하나로 필요가 있다.

 

18. 다음 소켓 함수의 기능을 간단히 설명하시오

socket() :  매개변수로 지정한 유형에 따라 소켓을 생성한다

bind() : socket()함수로 생성된 소켓에 주소를 부여한다.

listen()  첫번째 매개변수로 표시한 소켓을 활성화 한다. 

accept()  대기하다가 클라이언트의 요청에 따라 새로운 소켓을 생성하고 연결한다.

connect()  name이 가리키는 서버와 연결설정을 시도한다

send()  연결형 서비스를 제공하는 환경에서 데이터를 전송하는 역할을 한다.

recv()  연결형 서비스에서 데이터를 수신하는 역할을 한다.

 

19. socket()함수에서 TCP와 UDP용 소켓을 생성하는 프로그램을 작성하시오

#include <sys/types.h>

#include<sys/socket.h>

int sd0=socket(AF_INET,SOCK_STREAM,0);//TCP용 소켓

int sd1=socket(AF_INET, SOCK_DGRAMK, 0);//UDP용 소켓

 

20. 인터넷 도메인에서 bind() 함수를 이용해 IP 주소는 211.223.201.30. 포트번호는 5000인 소켓을 생성하는 프로그램을 작성하시오

#include <sys/types.h>

#include<sys/socket.h>

int sd0=socket(AF_INET,SOCK_STREAM,0);//TCP용 소켓

struct sockaddr_in addr;

addr.sin_family=AF_INET;

addr.sin_addr.s_addr=htonl(inet_addr(“211.223.201.30”));

addr.sin_port=htons(5000);

 

21. INADD_ANY의 필요성을 설명하시오

개발된 프로그램이 여러 컴퓨터에서 실행되는 경우, 각 실행 파일에 개별 호스트의 IP 주소를 지정하여 컴파일하기는 현실적으로 불가능하다. 그래서 INADD_ANY를 사용하여 호스트의 IP주소로 자동 대체되게 한다.

 

23. accept()와 connect() 함수를 이용해 연결을 설정하는 프로그램을 작성하시오

#include <sys/types.h>

#include <sys/socket.h>

 

main()

{

int sd, new;

struct sockaddr_in addr;

struct sockaddr_in client;

int client_len;

sd = socket(AF_INET, SOCK_STREAM, 0);

if (sd == -1)

{

perror("socket");

exit(1);

}

 

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = htonl(INADDR_ANY);

addr.sin_port = htons(5010);

if (bind(sd, (struct sockaddr*)&addr, sizeof(addr)) == -1)

{

perror("bind");

exit(1);

}

if (listen(sd, 5) == -1)

{

perror("listen");

exit(1);

}

while ((new = accept(sd, (struct sockaddr*)&client, &client_len)) != -1)

{

if (fork() == 0)

{

close(sd);

work(new);

close(new);

exit(0);

}

close(new);

}

}

 

#include <sys/types.h>

#include <sys/socket.h>

 

main()

{

int sd, new;

struct sockaddr_in addr;

 

 

sd = socket(AF_INET, SOCK_STREAM, 0);

if (sd == -1)

{

perror("socket");

exit(1);

}

 

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = htonl(inet_addr("211.223.201.30"));

addr.sin_port = htons(5010);

 

if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) == -1)

{

perror("connect");

exit(1)''

}

}

24. 연결형 서비스를 제공하는 서버와 클라이언트 프로그램을 작성하시오

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

#define TIME_SERVER "211.223.201.30"

#define TIME_PORT 5010

 

main()

{

int sock;

struct sockaddr_in server;

char buf[256];

 

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)

exit(1);

server.sin_family = AF_INET;

server.sin_addr.s_addr = htonl(inet_addr(TIME_SERVER));

server.sin_port = htos(TIME_PORT);

 

if (connect(sock, (struct sockaddr*)&server, sizeof(server)))

exit(1);

 

if (recv(sock, buf, sizeof(buf), 0) == -1)

exit(1);

printf("Time information from server is %s", buf);

close(sock);

 

}

 

#include <sys/types.h>

#include <sys/socket.h>

#include <netline/in.h>

 

#include <time.h>

 

#define TIME_PORT 5010

 

main()

{

int scok, sock2;

struct sockaddr_in server, client;

int len;

char buf[256];

time_t today;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)

exit(1);

server.sin_family = AF_INET;

server.sin_addr.s_addr = htonl(INADDR_ANY);

server.sin_port = htons(TIME_PORT);

 

if (bind(sock, (struct sockaddr*)&server, sizeof(server)))

exit(1);

 

if (listen(sock, 5))

exit(1);

 

while (1)

{

if ((sock2 = accept(sock, (struct sockaddr*)&client, &len)) == -1)

exit(1);

time(&today);

strcpy(buf, ctime(&today));

send(sock2, buf, strlen(buf) + 1, 0);

close(sock2);

}

}

 

25. 비연결형 서비스를 제공하는 서버와 클라이언트 프로그램을 작성하시오

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

#define TIME_SERVER "211.223.201.30"

#define TIME_PORT 5010

 

main()

{

int sock;

struct sockaddr_in server,client;

int server_len = sizeof(server);

char buf[256];

int buf_len;

 

 

server.sin_family = AF_INET;

server.sin_addr.s_addr = htonl(inet_addr(TIME_SERVER));

server.sin_port = htos(TIME_PORT);

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)

exit(1);

client.sin_family = AF_INET;

client.sin_addr.s_addr = htonl(INADDR_ANY);

client.sin_port = htons(0);

 

if (bind(sock, (struct sockaddr*)&client, sizeof(client)) < 0)

exit(1);

buf[0] = '?'; buf[1] = '\0';

buf_len = sendto(sock, buf, strlen(buf) + 1, 0, (struct sockaddr*)&server, server_len);

if (buf_len < 0)

exit(1);

buf_len = recvform(sock, buf, 256, 0, (struct sockaddr*)0, (int*)0);

if (buf_len < 0)

exit(1);

printf("Time information from server is %s", buf);

close(sock);

 

}#include <sys/types.h>

#include <sys/socket.h>

#include <netline/in.h>

 

#include <time.h>

 

#define TIME_PORT 5010

 

main()

{

int scok;

struct sockaddr_in server, client;

int server_len;

int client_len;

char buf[256];

int buf_len;

time_t today;

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)

exit(1);

server.sin_family = AF_INET;

server.sin_addr.s_addr = htonl(INADDR_ANY);

server.sin_port = htons(TIME_PORT);

 

if (bind(sock, (struct sockaddr*)&server, sizeof(server)))

exit(1);

 

if (listen(sock, 5))

exit(1);

 

while (1)

{

buf_len = recvfrom(sock, buf, 256, 0, (struct sockaddr*)&client, &client_len);

if (buf_len < 0)

exit(1);

printf("Server:Got:%s\n", buf);

time(&today);

strcpy(buf, ctime(&today));

sendto(sock, buf, strlen(buf) + 1, 0, (struct sockaddr*)&client, client_len);

 

}

}