유닉스 소켓-핵심 기능

이 장에서는 완전한 TCP 클라이언트 및 서버를 작성하는 데 필요한 핵심 소켓 기능에 대해 설명합니다.

다음 다이어그램은 완전한 클라이언트 및 서버 상호 작용을 보여줍니다.

소켓 기능

네트워크 I / O를 수행하려면 프로세스가 가장 먼저 수행해야하는 작업은 소켓 함수를 호출하고 원하는 통신 프로토콜 유형 및 프로토콜 제품군을 지정하는 것입니다.

#include <sys/types.h>
#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 케트 소켓

이 장에서는 IPv4를 제외한 다른 프로토콜에 대해서는 다루지 않습니다.

type− 원하는 소켓 종류를 지정합니다. 다음 값 중 하나를 취할 수 있습니다.

유형 기술
SOCK_STREAM 스트림 소켓
SOCK_DGRAM 데이터 그램 소켓
SOCK_SEQPACKET 시퀀스 된 패킷 소켓
SOCK_RAW 원시 소켓

protocol − 인수는 아래에 주어진 특정 프로토콜 유형으로 설정해야합니다. 또는 주어진 패밀리 및 유형 조합에 대한 시스템 기본값을 선택하려면 0을 설정해야합니다.

실험 계획안 기술
IPPROTO_TCP TCP 전송 프로토콜
IPPROTO_UDP UDP 전송 프로토콜
IPPROTO_SCTP SCTP 전송 프로토콜

연결 기능

연결 기능은 TCP 서버와의 연결을 설정하기 위해 TCP 클라이언트에 의해 사용됩니다.

#include <sys/types.h>
#include <sys/socket.h>

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

이 호출은 서버에 성공적으로 연결되면 0을 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • serv_addr − 대상 IP 주소와 포트를 포함하는 struct sockaddr에 대한 포인터입니다.

  • addrlen − sizeof (struct sockaddr)로 설정합니다.

바인드 기능

바인드 함수는 소켓에 로컬 프로토콜 주소를 할당합니다. 인터넷 프로토콜에서 프로토콜 주소는 16 비트 TCP 또는 UDP 포트 번호와 함께 32 비트 IPv4 주소 또는 128 비트 IPv6 주소의 조합입니다. 이 함수는 TCP 서버에서만 호출됩니다.

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *my_addr,int addrlen);

이 호출은 주소에 성공적으로 바인딩되면 0을 반환하고 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • my_addr − 로컬 IP 주소와 포트를 포함하는 struct sockaddr에 대한 포인터입니다.

  • addrlen − sizeof (struct sockaddr)로 설정합니다.

IP 주소와 포트를 자동으로 입력 할 수 있습니다.

포트 번호 값이 0이면 시스템이 임의의 포트를 선택하고 IP 주소에 INADDR_ANY 값이 있으면 서버의 IP 주소가 자동으로 할당됩니다.

server.sin_port = 0;  		     
server.sin_addr.s_addr = INADDR_ANY;

NOTE− 1024 미만의 모든 포트는 예약되어 있습니다. 다른 프로그램에서 사용하는 포트가 아닌 경우 1024 이상 65535 미만의 포트를 설정할 수 있습니다.

듣는 기능

듣기 기능은 TCP 서버에 의해 호출과 두 개의 작업을 수행한다 -

  • listen 함수는 연결되지 않은 소켓을 수동 소켓으로 변환하여 커널이이 소켓으로 향하는 들어오는 연결 요청을 수락해야 함을 나타냅니다.

  • 이 함수의 두 번째 인수는 커널이이 소켓에 대해 대기해야하는 최대 연결 수를 지정합니다.

#include <sys/types.h>
#include <sys/socket.h>

int listen(int sockfd,int backlog);

이 호출은 성공시 0을 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • backlog − 허용 된 연결 수입니다.

동의 기능

동의 기능이 완성 된 연결 대기열의 전면에서 다음의 완료 연결을 반환하는 TCP 서버에 의해 호출됩니다. 호출의 서명은 다음과 같습니다.

#include <sys/types.h>
#include <sys/socket.h>

int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

이 호출은 성공시 음수가 아닌 설명자를 반환하고, 그렇지 않으면 오류시 -1을 반환합니다. 반환 된 디스크립터는 클라이언트 소켓 디스크립터로 간주되며 모든 읽기-쓰기 작업은 클라이언트와 통신하기 위해이 디스크립터에서 수행됩니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • cliaddr − 클라이언트 IP 주소와 포트를 포함하는 struct sockaddr에 대한 포인터입니다.

  • addrlen − sizeof (struct sockaddr)로 설정합니다.

전송 기능

송신 기능은 스트림 소켓 또는 연결된 데이터 그램을 통해 데이터를 전송하기 위해 사용된다. UNCONNECTED 데이터 그램 소켓을 통해 데이터를 보내려면 sendto () 함수를 사용해야합니다.

당신은 사용할 수 있습니다 쓰기 () 데이터를 전송하는 시스템 호출을. 그 서명은 다음과 같습니다-

int send(int sockfd, const void *msg, int len, int flags);

이 호출은 전송 된 바이트 수를 반환합니다. 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • msg − 전송하려는 데이터에 대한 포인터입니다.

  • len − 전송하려는 데이터의 길이 (바이트 단위)입니다.

  • flags − 0으로 설정됩니다.

RECV의 기능

RECV의 기능은 스트림 소켓 CONNECTED 또는 데이터 그램을 통해 데이터를 수신하는데 사용된다. UNCONNECTED 데이터 그램 소켓을 통해 데이터를 수신하려면 recvfrom ()을 사용해야합니다.

당신은 사용할 수 있습니다 읽기 () 데이터를 읽을 시스템 호출을. 이 호출은 도우미 함수 장에서 설명합니다.

int recv(int sockfd, void *buf, int len, unsigned int flags);

이 호출은 버퍼로 읽은 바이트 수를 반환합니다. 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • buf − 정보를 읽어 오는 버퍼입니다.

  • len − 버퍼의 최대 길이입니다.

  • flags − 0으로 설정됩니다.

sendto를 기능

sendto를 기능이 연결되지 않은 데이터 그램 소켓을 통해 데이터를 전송하는 데 사용됩니다. 그 서명은 다음과 같습니다-

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);

이 호출은 전송 된 바이트 수를 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • msg − 전송하려는 데이터에 대한 포인터입니다.

  • len − 전송하려는 데이터의 길이 (바이트 단위)입니다.

  • flags − 0으로 설정됩니다.

  • to − 데이터를 전송해야하는 호스트의 struct sockaddr에 대한 포인터입니다.

  • tolen − sizeof (struct sockaddr)로 설정합니다.

에 recvfrom의 기능

함수 recvfrom 함수가 연결되지 않은 데이터 그램 소켓으로부터 데이터를 수신하는데 사용된다.

int recvfrom(int sockfd, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);

이 호출은 버퍼로 읽은 바이트 수를 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • buf − 정보를 읽어 오는 버퍼입니다.

  • len − 버퍼의 최대 길이입니다.

  • flags − 0으로 설정됩니다.

  • from − 데이터를 읽어야하는 호스트의 struct sockaddr에 대한 포인터입니다.

  • fromlen − sizeof (struct sockaddr)로 설정합니다.

가까운 기능

확대 기능은 클라이언트와 서버 간의 통신을 닫기 위해 사용된다. 구문은 다음과 같습니다.

int close( int sockfd );

이 호출은 성공시 0을 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

종료 기능

셧다운 기능이 정상적으로 클라이언트와 서버 사이의 통신을 종료하는 데 사용됩니다. 이 기능은 닫기 기능 에 비해 더 많은 제어를 제공 합니다. 아래의 구문입니다 종료 -

int shutdown(int sockfd, int how);

이 호출은 성공시 0을 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • sockfd − 소켓 함수에 의해 반환 된 소켓 설명자입니다.

  • how − 숫자 중 하나를 입력하세요 −

    • 0 − 수신이 허용되지 않음을 나타냅니다.

    • 1 − 전송이 허용되지 않음을 나타냅니다.

    • 2− 전송과 수신이 모두 허용되지 않음을 나타냅니다. how 를 2로 설정 하면 close ()와 같습니다.

선택 기능

선택 기능은 쓰기, 읽기에 대한 준비가 준비 또는 대기 오류 상태가 지정된 파일 설명을 나타냅니다.

애플리케이션이 recv 또는 recvfrom을 호출 하면 해당 소켓에 대한 데이터가 도착할 때까지 차단됩니다. 애플리케이션은 들어오는 데이터 스트림이 비어있는 동안 다른 유용한 처리를 수행 할 수 있습니다. 또 다른 상황은 애플리케이션이 여러 소켓에서 데이터를 수신하는 경우입니다.

입력 큐에 데이터가없는 소켓에서 recv 또는 recvfrom 을 호출 하면 다른 소켓에서 데이터를 즉시 수신 할 수 없습니다. select 함수 호출은 프로그램이 모든 소켓 핸들을 폴링하여 non-blocking 읽기 및 쓰기 작업에 사용할 수 있는지 확인하도록함으로써이 문제를 해결합니다.

아래의 구문입니다 선택은 -

int select(int  nfds, fd_set  *readfds, fd_set  *writefds, fd_set *errorfds, struct timeval *timeout);

이 호출은 성공시 0을 반환하고, 그렇지 않으면 오류시 -1을 반환합니다.

매개 변수

  • nfds− 테스트 할 파일 설명 자의 범위를 지정합니다. select () 함수는 0에서 nfds-1 범위의 파일 설명자를 테스트합니다.

  • readfds− 입력시 읽을 준비가 된 파일 설명자를 지정하고 출력시 읽을 준비가 된 파일 설명자를 나타내는 fd_set 유형의 객체를 가리 킵니다 . 빈 집합을 나타 내기 위해 NULL 일 수 있습니다.

  • writefds− 입력시 쓰기 준비가되었는지 확인할 파일 설명자를 지정하고 출력시 쓰기 준비가 된 파일 설명자를 나타내는 fd_set 유형의 객체를 가리 킵니다 . 빈 집합을 나타 내기 위해 NULL 일 수 있습니다.

  • exceptfds− 입력시 보류중인 오류 조건이 있는지 확인할 파일 설명자를 지정하고 출력시 보류중인 오류 조건이있는 파일 설명자를 나타내는 fd_set 유형의 객체를 가리 킵니다 . 빈 집합을 나타 내기 위해 NULL 일 수 있습니다.

  • timeout− 선택 호출이 사용 가능한 I / O 작업에 대해 설명자를 폴링해야하는 시간을 지정하는 timeval 구조체를 가리 킵니다. 시간 초과 값이 0이면 select가 즉시 반환됩니다. 시간 초과 인수가 NULL이면 최소한 하나의 파일 / 소켓 핸들이 사용 가능한 I / O 작업을 위해 준비 될 때까지 select가 차단됩니다. 그렇지 않으면 제한 시간이 경과 한 후 또는 적어도 하나의 파일 / 소켓 설명자가 I / O 작업을 수행 할 준비가되면 select 가 반환됩니다.

select의 반환 값은 I / O 준비가 된 파일 설명자 집합에 지정된 핸들 수입니다. 타임 아웃 필드에 지정된 시간 제한에 도달하면 return 0을 선택합니다. 파일 설명자 세트를 조작하기 위해 다음 매크로가 존재합니다.

  • FD_CLR(fd, &fdset)− 파일 기술자 집합 fdset 에서 파일 기술자 fd에 대한 비트를 지 웁니다 .

  • FD_ISSET(fd, &fdset)− 파일 설명자 fd에 대한 비트 가 fdset가 가리키는 파일 설명자 세트에 설정되어 있으면 0이 아닌 값 을 반환 하고 그렇지 않으면 0을 반환합니다.

  • FD_SET(fd, &fdset) − 파일 기술자 세트 fdset에서 파일 기술자 fd에 대한 비트를 설정합니다.

  • FD_ZERO(&fdset) − 모든 파일 설명자에 대해 0 비트를 갖도록 파일 설명자 세트 fdset를 초기화합니다.

이러한 매크로의 동작은 fd 인수가 0보다 작거나 FD_SETSIZE보다 크거나 같은 경우 정의되지 않습니다.

fd_set fds;

struct timeval tv;

/* do socket initialization etc.
tv.tv_sec = 1;
tv.tv_usec = 500000;

/* tv now represents 1.5 seconds */
FD_ZERO(&fds);

/* adds sock to the file descriptor set */
FD_SET(sock, &fds); 

/* wait 1.5 seconds for any data to be read from any single socket */
select(sock+1, &fds, NULL, NULL, &tv);

if (FD_ISSET(sock, &fds)) {
   recvfrom(s, buffer, buffer_len, 0, &sa, &sa_len);
   /* do something */
}
else {
   /* do something else */
}