UNP Chapter 4 - 기본 TCP 번들 인터페이스 프로그래밍

9421 단어 tcp
4.1. 개요
유닉스는 동시에 대량의 고객이 같은 서버에 연결될 때 합병성을 제공한다. 모든 고객 연결은 서버로 하여금 그를 위해 새로운 프로세스를 파생시키게 한다.여기에는 fork의 모든 고객 단일 프로세스 모델(one-process-per-client 모델)만 고려하고, 라인을 토론할 때 다른 모델과 모든 고객 단일 프로세스 모델(one-thread-per-client 모델)을 고려한다.
4.2. socket 함수
네트워크 I/O를 실행하기 위해 프로세스가 해야 할 첫 번째 일은 socket 함수를 호출하고 원하는 통신 프로토콜 유형(IPv4를 사용하는 TCP, IPv6를 사용하는 UDP, 유닉스 필드 바이트 흐름 프로토콜 등)을 지정하는 것이다.
#include <sys/socket.h>
int socket(int family, int type, int protocol); // : - , -1 -

family는 프로토콜족을 가리키는데, 다음과 같다.
AF_INET     IPv4 
AF_INET6 IPv6
AF_LOCAL   Unix
AF_ROUTE  
AF_KEY

type는 플러그 인터페이스 유형을 가리키며, 다음과 같습니다.
SOCK_STREAM   
SOCK_DGRAM
SOCK_RAW

프로토콜 매개 변수는 원본 인터페이스에 사용하지 않는 한 일반적으로 0으로 설정됩니다
모든 인터페이스 패밀리와 type의 조합이 유효한 것은 아닙니다. 유효한 조합은 다음과 같습니다.
                  AF_INET    AF_INET6    AF_LOCAL   AF_ROUTE   AF_KEY
SOCK_STREAM TCP TCP Yes
SOCK_DGRAM UDP UDP Yes
SOCK_RAW IPv4 IPv6 Yes Yes

cket 함수는 성공할 때 작은 비음정수치를 되돌려줍니다. 파일 설명자와 유사합니다. 인터페이스 설명자 (socket descriptor) 를 줄여서 플러그인 (sockfd) 이라고 합니다.AF_xxx 및 PF_xxx
AF_접두사는 주소족(address family), PF_접두사는 프로토콜 패밀리를 나타냅니다.4.3. connect 함수
TCP 고객은 connect 함수로 TCP 서버와의 연결을 설정합니다
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen); // : 0- , -1 -

4.4. bind 함수
함수bind 인터페이스에 로컬 프로토콜 주소 할당
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen); // : 0- , -1 -

A process can bind a specific IP address to its socket. the IP address must belong to an interface on the host.
IPv4의 경우 와일드카드 주소는 일반 INADDR_일반적으로 값이 0인 경우 커널에 IP 주소를 선택하도록 알립니다. 예를 들어
struct sockaddr_in servaddr;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard */

IPv6의 경우 다음과 같이 시스템 할당 변수 in6addr_any 및 일반 IN6ADDR_로 초기화ANY_INIT
struct sockaddr_in6 serv;
serv.sin6_addr = in6addr_any; /* wildcard */

4.5. listen 함수
#include <sys/socket.h>
int listen(int sockfd, int backlog); // : 0- -1 -

함수 listen은 TCP 서버에서만 호출됩니다. 두 가지 일을 합니다.
1. 함수 socket을 플러그인 인터페이스를 만들 때, 이것은 주동적인 플러그인 인터페이스로 가정된다. 즉, 플러그인connect를 호출하여 연결을 시작하는 클라이언트 플러그인 인터페이스이다. 함수 listen은 연결되지 않은 플러그인 인터페이스를 피동적인 플러그인 인터페이스로 바꾸어 내부 핵이 플러그인을 가리키는 연결 요청을 받아들여야 한다는 것을 지시한다.2. 함수의 두 번째 매개 변수는 커널이 이 플러그 입구에 줄을 서는 최대 연결 개수를 규정한다.
일반적으로 bind 함수는 함수 socket과bind를 호출한 후에 함수 accept를 호출하기 전에 호출해야 한다.
4.6. accept 함수
함수 accept는 TCP 서버에서 호출됩니다. 연결된 대기열 헤더에서 다음 완료된 연결을 되돌려줍니다. 연결된 대기열이 비어 있으면 프로세스가 잠듭니다. (플러그 인터페이스가 부족한 차단 방식이라고 가정합니다.)
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr * cliaddr, socklen_t * addrlen); // : -OK, -1 -

매개 변수cliaddr와addrlen은 상대방의 프로세스 (고객) 를 연결하는 프로토콜 주소를 되돌려주는 데 사용되며,addrlen은value-result 매개 변수입니다.호출하기 전에, 우리는 *addrlen이 가리키는 정수 값을cliaddr가 가리키는 인터페이스 주소 구조의 길이로 설정합니다. 되돌아올 때, 이 정수 값은 인터페이스 주소 구조에 있는 정확한 바이트 숫자입니다.함수 accept가 성공적으로 실행되면 반환값은 커널에서 자동으로 생성된 새로운 플러그인으로 고객과의 TCP 연결을 대표합니다.함수accept를 토론할 때, 항상 첫 번째 인자를 감청 플러그인 인터페이스 (listening socket) 설명자 (함수 socket에서 생성된 설명자가 있으며, 함수bind와listen의 첫 번째 인자로 사용됨) 라고 하고, 그 반환값을 연결 플러그인 인터페이스 (connected socket) 설명자라고 한다.
이 두 개의 플러그인 인터페이스를 분리하는 것은 매우 중요하다. 주어진 서버는 항상 하나의 감청 플러그인 인터페이스만 생성하고 존재한다. 이 서버가 닫힐 때까지 플러그인은 모든 받아들여진 고객의 연결을 위해 이미 연결된 플러그인 인터페이스를 만든다. (즉, 플러그인은 그것을 위해 TCP 삼중 악수 과정을 완성했다) 서버가 특정한 고객의 서비스를 완성할 때 플러그인 인터페이스를 닫는다.
4.7. fork 및 exec 함수
함수 fork는 Unix에서 새 프로세스를 파생하는 유일한 방법입니다.
#include <unistd.h>
pid_t fork(void); // : 0, ID,-1 -

함수 fork 호출은 한 번에 두 번 되돌려줍니다.호출 프로세스(아버지 프로세스라고도 함)에서 한 번 되돌아옵니다. 되돌아오는 값은 새 파생 프로세스(하위 프로세스라고도 함)의 프로세스 ID 번호입니다. 하위 프로세스에서 다시 한 번 되돌아옵니다. 되돌아오는 값은 0입니다.따라서 값을 되돌려 현재 프로세스가 하위 프로세스인지 부모 프로세스인지 판단할 수 있습니다.디스크에 파일 형식으로 저장된 실행 가능한 프로그램이 유닉스에서 실행되는 유일한 방법은 기존 프로세스에서 6개의 exec 함수 중 하나를 호출하는 것이다.exec는 현재 프로세스 이미지를 새 프로그램으로 대체하고, 이 새 프로그램은 일반적으로main 함수부터 실행되며, 프로세스 ID는 변하지 않습니다.우리는 일반적으로 exec를 호출하는 프로세스를 호출 프로세스 (calling process) 라고 하고, 새로 실행하는 프로그램을 새 프로그램 (new 프로그램) 이라고 부른다.
#include <unistd.h>
int execl(const char * pathname, const char * arg0, ... /* (char * )0 */);
int execv(const char * pathname, char * const argv[]);
int execle(const char * pathname, const char * arg0, ... /* (char * )0, char * const envp[] */);
int execve(const char * pathname, char * const argv[], char * const envp[]);
int execlp(const char * filename, const char * arg0, ... /* (char *) 0 */);
int execvp(const char * filename, char * const argv[]);

이 함수들은 오류가 발생했을 때만 호출자를 되돌려줍니다. 그렇지 않으면 새 프로그램의 시작에 제어권이 전달됩니다. 보통 함수main에 전달됩니다.execve만 내부 핵의 시스템 호출이고, 다른 다섯 개의 함수는 모두 execve의 라이브러리 함수를 호출합니다.
4.8. Concurrent 서버 동시 서버
4.9. close 함수
#include <unistd.h>
int close(int sockfd); // : 0 -OK, -1 -

4.10. getsockname 및 getpeername 함수
getsockname는 플러그인 인터페이스와 연결된 로컬 프로토콜 주소를 되돌려주고, getpeername는 플러그인과 연결된 원격 프로토콜 주소를 되돌려줍니다.
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr * localaddr, socklen_t * addrlen); // 0-OK, -1 -
int getpeername(int sockfd, struct sockaddr * peeraddr, socklen_t * addrlen); // 0-OK, -1 -

두 함수의 마지막 매개 변수는value-result 매개 변수입니다. 모두 바늘localaddr나peeraddr가 가리키는 인터페이스 주소 구조를 채웁니다.
4.11. 작은 매듭
모든 고객과 서버는 socket을 호출하기 시작해서 인터페이스 설명자를 되돌려줍니다.그리고 클라이언트는connect를 호출하고 서버는bind,listen,accept를 호출합니다.플러그인 인터페이스는 일반적으로 표준close 함수로 닫히며, 물론 함수shutdown으로도 닫을 수 있습니다.대부분의 TCP 서버는 모든 고객이 연결된 서버를 처리하기 위해 fork를 호출하여 실행합니다.대부분의 UDP 서버는 교체됩니다.

좋은 웹페이지 즐겨찾기