네트워크 프로그래밍 4 : Linux에서 제공하는 API에 대한 간략한 분석 (소켓 서버 및 클라이언트 개발 단계)

Linux에서 제공하는 API에 대한 간략한 분석 (소켓 서버 및 클라이언트 개발 단계)

1. 연결 프로토콜 : (TCP / UDP)

//创建套接字
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,int type,int protocol);
返回sockfd---失败返回-1

도메인 :
일반적으로 사용되는 프로토콜 제품군을 지정 합니다.AF_INET, 인터넷 프로토콜 제품군 (TCP / IP 프로토콜 제품군)을 나타냅니다.

AF_INET IPV4 인터넷 도메인
AF_INET6 IPV6 인터넷 도메인
AF_UNIX unix 도메인
AF_ROUTE 라우팅 소켓
AF_KEY 키 소켓
AF_UNSPEC 지정되지 않음

type 매개 변수는 소켓 유형을 지정합니다.
SOCK_STREAM:
스트리밍 소켓은 신뢰할 수있는 연결 지향 통신 흐름을 제공하며 TCP 프로토콜 을 사용하여 데이터 전송의 정확성과 순서를 보장합니다.
SOCK_DGRAM:
데이터 그램 소켓은 비 연결형 서버를 정의하며 데이터는 독립적 인 메시지를 통해 전송되며 무질서하고 신뢰성을 보장하지 않으며 오류가 없으며 데이터 그램 프로토콜 UDP를 사용합니다 .
SOCK_RAW:
프로그램이 기본 프로토콜을 사용하도록 허용합니다. 원래 소켓은 IP 또는 ICMP와 같은 기본 프로토콜에 직접 액세스하기 위해 실행됩니다. 강력하지만 사용하기 불편합니다. 주로 일부 프로토콜의 개발에 사용됩니다 .


프로토콜
에는 일반적으로 "0
0 유형에 해당하는 기본 프로토콜 선택
== IPPROTO_TCP TCP 전송 프로토콜 ==
IPPROTO_UDP UDP 전송 프로토콜
IPPROTO_SCTP SCTP 전송 프로토콜
IPPROTO_TIPC TIPC 전송 프로토콜

2. IP 번호, 포트 번호 및 해당 설명 어 할당 기능 : bind () 함수

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

bind () 함수는 주소 계열의 특정 주소를 소켓에 할당합니다. 예를 들어, AF_INET 및 AF_INET6에 해당하는 것은 소켓에 ipv4 또는 ipv6 주소와 포트 번호 조합을 할당하는 것입니다.

기능 : IP 주소 및 포트 번호를 socketfd
매개 변수 에 바인딩하는 데 사용됩니다 .
sockfd: socket () 함수에 의해 생성되고 소켓을 고유하게 식별하는 소켓 설명 단어입니다. bind () 함수는이 디스크립터에 이름을 바인드합니다.
addr: 바인딩 할 sockfd를 가리키는 const 구조체 sockaddr * 포인터프로토콜 주소
Addrlen: 주소의 길이에 해당합니다.

프로토콜 주소 구조소켓이 생성 될 때 주소 프로토콜 패밀리에 따라 다릅니다. 예를 들어, ipv4는 다음에 해당합니다.

struct sockaddr_in {
    
    
    sa_family_t    sin_family; //协议族
    in_port_t      sin_port;   //端口号
    struct in_addr sin_addr;   //IP地址结构体
};
struct in_addr {
    
    
    uint32_t       s_addr;     /* address in network byte order */
};

일반적으로 서버는 서비스를 제공하는 데 사용되는 서버가 시작될 때 잘 알려진 주소 == (예 : ip 주소 + 포트 번호) == 바인딩되며 클라이언트는이를 통해 서버에 연결할 수 있습니다. 클라이언트를 지정할 필요가 없으며 시스템은 자동으로 포트 번호와 자체 IP 주소 조합을 할당합니다. 이것이 일반적으로 서버는 수신하기 전에 bind ()를 호출하지만 클라이언트는이를 호출하지 않고 대신 connect ()시 시스템이 임의로 생성합니다.

3.listen () 모니터링 기능, connect () 연결 기능

서버의 경우 socket ()과 bind ()를 호출 한 후 listen ()을 호출하여 소켓을 모니터링하고, 이때 클라이언트가 connect ()를 호출하여 연결 요청을 보내면 서버가 요청을받습니다.

#include <sys/types.h> 
#include <sys/socket.h>
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

청취 기능의 첫 번째 매개 변수는 모니터링 할 매개 변수입니다.소켓 설명 단어, 두 번째 매개 변수는 해당 소켓이 대기열에 넣을 수있는 대기열입니다.최대 연결 수. socket () 함수에 의해 생성 된 소켓은 기본적으로 활성 유형이며 listen 함수는 소켓을 수동 유형으로 바꾸고 클라이언트의 연결 요청을 기다립니다.

연결 기능의 첫 번째 매개 변수는클라이언트의 소켓 설명, 두 번째 매개 변수는서버의 소켓 주소, 세 번째 매개 변수는 소켓 주소입니다.길이. 클라이언트는 connect 함수를 호출하여 TCP 서버와 연결을 설정합니다.
  
4.accept () 수신 요청 함수

TCP 서버가 socket (), bind () 및 listen ()을 차례로 호출 한 후 지정된 소켓 주소를 수신합니다. TCP 클라이언트가 socket ()과 connect ()를 차례로 호출 한 후 TCP 서버에 연결 요청을 보냅니다. TCP 서버는 요청을 수신 한 후 accept () 함수를 호출하여 요청을 수신하므로 연결이 설정됩니다. 그런 다음 네트워크 I / O 작업, 즉 일반 파일과 유사한 I / O 작업을 읽고 쓸 수 있습니다.

#include <sys/types.h> 
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //返回连接connect_fd

함수의 세 가지 매개 변수는 다음과 같습니다.

sockfd : 위에서 설명한 리스닝 소켓입니다.이 소켓은 포트를 모니터링하는 데 사용됩니다. 클라이언트가 서버에 연결할 때이 포트 번호를 사용하며이 포트 번호는 현재이 소켓에 연결되어 있습니다. 연관 됨. 물론 클라이언트는 소켓의 세부 사항을 알지 못하고 주소와 포트 번호 만 알고 있습니다.
addr : 반환 값을받는 데 사용되는 결과 매개 변수입니다.이 반환 값은 클라이언트의 주소를 지정합니다. 물론이 주소는 특정 주소 구조로 설명됩니다. 사용자는이 주소 구조의 종류를 알아야합니다. 고객 주소에 관심이없는 경우이 값을 NULL로 설정할 수 있습니다.
len : 모두가 생각하는 것처럼 결과의 매개 변수이기도하며 위의 addr 구조의 크기를 받아들이는 데 사용되며 addr 구조가 차지하는 바이트 수를 나타냅니다. 마찬가지로 NULL로 설정할 수도 있습니다.

accept가 성공적으로 반환되면 서버와 클라이언트가 연결을 올바르게 설정하고 서버는 accept가 반환 한 소켓을 통해 클라이언트와의 통신을 완료합니다.

노트:
Accept는 클라이언트 연결이 설정되고 반환 될 때까지 기본적으로 프로세스를 차단하고 새로 사용 가능한 연결 소켓 인 소켓을 반환합니다.

이 시점에서 두 가지 유형의 소켓을 구분해야합니다.

청취 소켓: 리스닝 소켓은 accept 매개 변수 sockfd와 동일하며 리스닝 소켓입니다. listen 함수가 호출되면 서버는 socket () 함수를 호출하기 시작합니다. 리스닝 소켓 디스크립터 (모니터링 소켓)라고합니다.
소켓 연결: 소켓은 능동적으로 연결된 소켓에서 청취 소켓으로 변경되고 accept 함수는 네트워크가 이미 존재하는 지점을 나타내는 연결된 소켓 (연결된 소켓)의 설명을 반환합니다. 연결.

서버는 일반적으로 서버의 수명주기 동안 항상 존재하는 청취 소켓 설명 자만 만듭니다. 커널은 서버 프로세스에서 수락 한 각 클라이언트 연결에 대해 연결된 소켓 설명자를 생성하고 서버가 특정 클라이언트에 대한 서비스를 완료하면 해당 연결 소켓 설명자가 닫힙니다.

연결 소켓 socketfd_new는 클라이언트와 통신하기 위해 새 포트를 차지하지 않으며 여전히 청취 소켓 socketfd와 동일한 포트 번호를 사용합니다.
  
5. read (), write () 및 기타 함수

다음과 같은 네트워크 I / O 작업 그룹이 있습니다.

read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()

6. 닫기 기능

int close(int fd);

TCP 소켓을 닫는 기본 동작은 소켓을 닫힌 것으로 표시 한 다음 즉시 호출 프로세스로 돌아가는 것입니다. 설명 단어는 더 이상 호출 프로세스에서 사용할 수 없습니다. 즉, 더 이상 읽기 또는 쓰기의 첫 번째 매개 변수로 사용할 수 없습니다.

노트: 닫기 작업은 해당 소켓 설명 단어 -1의 참조 횟수 만 만들고 참조 횟수가 0 인 경우에만 TCP 클라이언트가 서버에 연결 종료 요청을 전송하도록 트리거합니다.

7. 주소 변환 API :

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
//把字符串形成的“192.168.1.123”转为网络能识别的格式
char *inet_ntoa(struct in_addr in);
//把网络格式的ip地址转化为字符串形式

8. 엔디안 변환 API :

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);//返回网络字节序的值
uint16_t htons(uint16_t hostshort);//返回网络字节序的值
uint32_t ntohl(uint32_t netlong);//返回主机字节序的值uint32_t
uint16_t ntohs(uint16_t netshort);//返回主机字节序的值

h는 host, n은 net, s는 short (2 바이트), l은 long (4 바이트)을 나타내며, 위의 4 가지 함수를 통해 호스트 바이트 순서와 네트워크 바이트 순서 간의 변환을 실현할 수 있습니다. 때로는 사용할 수 있습니다INADDR_ANY, INADDR_ANY는 가져올 운영 체제의 주소를 지정합니다.

위의 API를 통해 클라이언트와 서버 간의 코드 작성을 완료 할 수 있습니다.

코드 구현은 다음 섹션을 참조하십시오.네트워크 프로그래밍 5설명

추천

출처blog.csdn.net/weixin_40734514/article/details/108555217