TCP/IP 통신 프로그램을 만들어보기 전에 운영 체제 및 언어에 맞는 통신 라이브러리에 대해서 분석해보려고 한다.
socket Library네트워크 동신을 구현하는데 사용되는 Python 표준 라이브러리이다. TCP, UDP, raw 소켓 등 다양한 소켓 프로그래밍을 쉽게 구현할 수 있다.
AF_INET : IPv4 주소 체계AF_INET6 : IPv6 주소 체계AF_UNIX : 로컬 UNIX 소켓SOCK_STREAM : TCP 소켓SOCK_DGRAM: UDP 소켓SOCK_RAW : RAW 소켓socket.socket(family, type) : 인자로 받은 네트워크 계열(family)와 소켓 유형(type)에 맞는 socket 생성s = socket.socket(AF_INET, SOCK_STREAM)
bind((host ,port)) : 소켓을 특정 IP 주소와 Port에 바인딩server_socket.bind(('0.0.0.0', 8080))
Binding이란?
네트워크 소켓을 특정 IP와 Port 번호에 할당하여 생성된 소켓이 해당 IP주소와 포트 번호를 통해 통신할 수 있게 된다.
Server 소켓의 경우, 클라이언트가 접속할 수 있는 고유한 네트워크 주소를 지정해야한다. 그에 따라 IP 주소 및 포트 번호를 바인딩해야한다.
Client 소켓의 경우,bind()를 명시적으로 호출하지 않으면, 커널은connect()를 호출할 때 자동으로 사용 가능한 로컬 IP와 Port를 선택하여 소켓에 바인딩
listen(backlog) : TCP Server 소켓을 대기 상태로 변환, backlog 파라미터는 아직 처리되지 않은 Client 연결 요청 대기 수socket.listen(2)
accpet() : 연결 요청을 수락하고 새로운 소켓을 반환, 반환되는 소켓은 클라이언트와 개별적인 연결을 처리하기 위한 새로운 소켓이다. 해당 소켓은 서버 소켓과는 별개로, 클라이언트와 서버 간의 통신을 전담conn, addr = socket.accept()
connect((host, port)) : Client 소켓이 서버에 연결 요청하는 함수socket.connet(('0,0,0,0', 8080))
send(data) : accept 함수를 통해 생성된 socket을 통해 데이터를 보내는 함수로 TCP 소켓에서 주로 사용conn.send("Hello, Client!")
recv(buffer_size) : socket을 통해 데이터 수신, TCP 소켓에서 주로 사용buffer_size = 2048
data = socket.recv(buffer_size)
buffer_size는 프로그래머가 필요에 따라 자유롭게 설정할 수 있다. 네트워크 환경에 맞추어 최적의buffer_size를 설정하여 효율성을 높일 수 있다.
sendto(data, (host, port)) : 데이터를 특정 주소로 보냄, UDP 소켓에서 주로 사용socket.sendto(data, (host, port))
recvfrom(buffer_size) : 특정 주소로 부터 데이터 수신, UDP 소캣 주로 사용data, addr = s. recvfrom(2048)
표준 C 라이브러리의 소캣 관련 헤더 파일과 함수들 이용
<sys/types.h> : 다양한 자료형의 정의와 시스템 호출 인터페이스와 관련된 자료형 포함<sys/socket.h> : 소켓 함수 및 자료형 정의 포함<netinet/in.h> : 인터넷 주소 구조체 정의와 상수 포함<arpa/inet.h> : IP 주소 변환 함수 포함<unistd.h> : POSIX 운영 체제 API 포함, 주로 파일 디스크럽터를 다루는 함수들이 정의되어 있고 소켓 프로그래밍에서도 사용socket : 소켓을 생성하는 함수
int socket(int domain, int type, int protocol);domain : Address family, 소켓이 사용할 네트워크 프로토콜 정의.type : Socket Type, 데이터 송수신 방식 정의.protocol : 사용될 특정 프로토콜 지정. 일반적으로 0으로 지정.-1.bind : 소켓을 바인딩 하는 함수
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockfd : 바인딩할 소켓 디스크립터.addr : 소켓을 바인딩할 주소 구조체의 포인터. 보통 sockaddr_in 또는 sockaddr_in6을 사용.addrlen : 주소 구조체의 크기.0-1listen: 서버 소켓을 연결 대기 상태로 설정하는 함수
int listen(int sockfd, int backlog);sockfd : bind()를 통해 바인딩된 소켓 디스크립터, 해당 소켓을 연결 요청 대기 상태로 전환backlog : 대기열의 최대 길이, 몇 개의 연결 요청을 대기 상태로 둘 것인지 지정.0-1accept : Client의 연결 요청을 수락하는 함수로 새로운 소켓과 Client 주소 정보 반환
int listen(int sockfd, struct sockaddr *addr, socklen_t *addrlen);sockfd : listen() 상태로 설정된 서버 소켓 디스크립터addr : 연결을 요청한 클라이언트의 주소 정보가 저장될 구조체addrlen : 위 구조체의 크기(입출력용)-1connect : Client 소켓이 서버에 연결 요청을 보내는 함수
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : 연결을 시도할 Client 소켓 디스크립터.addr : 서버의 주소 정보를 포함하고 있는 sockaddr 구조체의 포인터addrlen : 주소 구조체의 크기01send : TCP 소켓을 통해 데이터를 송신하는 함수
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd : 데이터를 송신할 소켓 디스크립터.buf : 송신할 데이터를 저장한 버퍼의 포인터.len : 송신할 데이터의 크기.flags : 송신 옵션. 보통 0으로 설정합니다.-1recv : TCP 소켓을 통해 데이터를 수신하는 함수
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sockfd : 데이터를 수신할 소켓 디스크립터.buf : 수신한 데이터를 저장할 버퍼의 포인터.len : 수신할 데이터의 최대 크기.flags : 수신 옵션. 보통 0으로 설정합니다.-1sendto : UDP 소켓을 통해 특정 주소로 데이터를 송신하는 함수
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
sockfd : 데이터를 송신할 소켓 디스크립터.buf: 송신할 데이터를 저장한 버퍼의 포인터.len: 송신할 데이터의 크기.flags: 송신 옵션. 보통 0으로 설정.to: 데이터를 송신할 대상 주소를 포함한 sockaddr 구조체의 포인터.tolen: 대상 주소 구조체의 크기.-1.recvfrom : UDP 소켓을 통해 특정 주소로부터 데이터를 수신하는 함수
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);sockfd : 데이터를 수신할 소켓 디스크립터.buf : 수신한 데이터를 저장할 버퍼의 포인터.len : 수신할 데이터의 최대 크기.flags : 수신 옵션. 보통 0으로 설정합니다.from : 데이터를 송신한 클라이언트의 주소를 저장할 sockaddr 구조체의 포인터.fromlen : 주소 구조체의 크기를 저장하고 반환할 포인터.-1setsockopt : 소켓 옵션을 설정하는 함수
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
sockfd : 옵션을 설정할 소켓 디스크립터.level : 옵션의 수준. 보통 SOL_SOCKET을 사용합니다.optname : 설정할 옵션의 이름.optval : 옵션 값을 저장한 버퍼의 포인터.optlen : 옵션 값의 크기.0-1getsockopt : 소켓 옵션을 가져오는 함수
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
sockfd : 옵션을 가져올 소켓 디스크립터.level : 옵션의 수준. 보통 SOL_SOCKET을 사용optname : 가져올 옵션의 이름.optval : 옵션 값을 저장할 버퍼의 포인터.optlen : 옵션 값의 크기를 저장하고 반환할 포인터.0 -1close : 소켓을 닫는 함수
int close(int fd);
fd : 닫을 소켓 디스크립터.01Winsock (Window)Windows 운영 체제에서 네트워크 프로그래밍을 위해 사용되는 API이다.

WSAStartup : Winsock 라이브러리 초기화 함수, Winsock 사용하기 전에 반드시 호출
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);WSACleanup : Winsock 라이브러리 종료 함수
int WSACleanup(void);socket : 소켓을 생성하는 함수. Address Family, Socket Type, Protocol을 인자로 받음
SOCKET socket(int af, int type, int protocol);af : Address Family, AF_INET은 IPv4, AF_INET6는 IPv6를 의미type : Socket Type, SOCK_STREAM은 TCP, SOCK_DGRAM은 UDP 소캣을 의미protocol : 사용될 Protocol, 대부분 0으로 지정하여 기본 Protocol 사용bind : 소켓을 특정 IP 주소와 Port에 바인딩하는 함수
int bind(SOCKET s, const struct sockaddr * addr, int addrlen);s : 바인딩할 소켓 디스크립터addr : 소켓을 바인딩할 주소 구조체의 포인터, sockaddr_in 혹은 sockaddr_in6를 사용addrlen : 주소 구조체의 크기listen : 서버 소켓을 연결 대기 상태로 설정 함수
int listen(SOCKET s, int backlog);
s : 연결 대기 상태로 설정할 소켓 디스크립터backlog : 대기열의 최대 길이, 몇 개의 요청을 대기 상태로 둘 것인지 지정accept : 클라이언트의 연결 요청을 수락하는 함수로 새로운 소켓과 클라이언트 주소 정보를 반환합니다.
SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);
connect : 클라이언트 소켓이 서버에 연결 요청을 보내는 함수입니다.
int connect(SOCKET s, const struct sockaddr *name, int namelen);
s : 연결을 시도할 클라이언트 소켓 디스크립터.name : 서버의 주소 정보를 포함하고 있는 sockaddr 구조체의 포인터.namelen : 주소 구조체의 크기.send : TCP 소켓을 통해 데이터를 송신하는 함수
int send(SOCKET s, const char *buf, int len, int flags);
s : 데이터를 송신할 소켓 디스크립터.buf : 송신할 데이터를 저장한 버퍼의 포인터.len : 송신할 데이터의 크기.flags : 송신 옵션. 보통 0으로 설정.recv : TCP 소켓을 통해 데이터를 수신하는 함수
int recv(SOCKET s, char *buf, int len, int flags);
s : 데이터를 수신할 소켓 디스크립터.buf : 수신한 데이터를 저장할 버퍼의 포인터.len : 수신할 데이터의 최대 크기.flags : 수신 옵션. 보통 0으로 설정.sendto : UDP 소켓을 통해 특정 주소로 데이터를 송신하는 함수
int sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen);
s : 데이터를 송신할 소켓 디스크립터.buf : 송신할 데이터를 저장한 버퍼의 포인터.len : 송신할 데이터의 크기.flags : 송신 옵션. 보통 0으로 설정.to : 데이터를 송신할 대상 주소를 포함한 sockaddr 구조체의 포인터.tolen : 대상 주소 구조체의 크기.recvto : UDP 소켓을 통해 특정 주소로부터 데이터를 수신하는 함수
int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
s : 데이터를 수신할 소켓 디스크립터.buf : 수신한 데이터를 저장할 버퍼의 포인터.len : 수신할 데이터의 최대 크기.flags : 수신 옵션. 보통 0으로 설정.from : 데이터를 송신한 클라이언트의 주소를 저장할 sockaddr 구조체의 포인터.fromlen : 주소 구조체의 크기를 저장하고 반환할 포인터.setsockopt : 소켓 옵션을 설정하는 함수.
int setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen);
s: 옵션을 설정할 소켓 디스크립터.level: 옵션의 수준. 보통 SOL_SOCKET을 사용.optname: 설정할 옵션의 이름.optval: 옵션 값을 저장한 버퍼의 포인터.optlen: 옵션 값의 크기.getsockopt : 소켓 옵션을 가져오는 함수
int getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen);
s : 옵션을 가져올 소켓 디스크립터.level : 옵션의 수준. 보통 SOL_SOCKET을 사용.optname : 가져올 옵션의 이름.optval : 옵션 값을 저장할 버퍼의 포인터.optlen : 옵션 값의 크기를 저장하고 반환할 포인터.closesocket : 소켓을 닫는 함수.
int closesocket(SOCKET s);
s : 닫을 소켓 디스크립터.getaddrinfo : 호스트 이름이나 서비스 이름을 IP 주소로 변환하는 함수.
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
node : 호스트 이름 또는 IP 주소.service : 서비스 이름 또는 포트 번호.hints : 추가 정보나 옵션을 제공하는 addrinfo 구조체의 포인터.res : 결과를 저장할 addrinfo 구조체의 포인터.getnameinfo : IP 주소를 호스트 이름과 서비스 이름으로 변환하는 함수.
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
sa : IP 주소 정보를 포함한 sockaddr 구조체의 포인터.salen : 주소 구조체의 크기.host : 호스트 이름을 저장할 버퍼의 포인터.hostlen : 호스트 이름 버퍼의 크기.serv : 서비스 이름을 저장할 버퍼의 포인터.servlen : 서비스 이름 버퍼의 크기.flags: 추가 옵션.inet_pton 및 inet_ntop: IP 주소 변환 함수로, 텍스트 형식의 IP 주소를 이진 형식으로 변환하거나 그 반대를 수행.
inet_ptonint inet_pton(int af, const char *src, void *dst);inet_ntopconst char *inet_ntop(int af, const void *src, char *dst, size_t size);inet_ptonaf : 주소 패밀리. 예를 들어 AF_INET은 IPv4를 AF_INET6는 IPv6를 의미src : 소스 주소 (텍스트 형식)dst : 목적지 주소 (이진 형식)inet_ntopaf : 주소 패밀리. 예를 들어 AF_INET은 IPv4를 AF_INET6는 IPv6를 의미src : 소스 주소 (텍스트 형식)dst : 목적지 주소 (이진 형식)size : 목적지 버퍼의 크기 Python socket Library : https://docs.python.org/ko/3/library/socket.html
POSIX socket Library : https://riptutorial.com/posix/example/22276/socket-basics
Winsock2 라이브러리를 이용하여 간단하 TCP/IP 서버와 클라이언트를 구현해보자 | C++ : https://woo-dev.tistory.com/135