소켓은 컴퓨터 네트워크에서 프로세스 간 통신을 가능하게 하는 인터페이스
소켓은 크게 두 가지로 구분하는데, 같은 호스트에서 프로세스 사이에 통신할 때 사용하는 유닉스 도메인 소켓과 인터넷을 통해 다른 호스트와 통신할 때 사용하는 인터넷 소켓이 있다.
TCP/IP 프로토콜의 전송 계층에서 사용하는 프로토콜에는 TCP와 UDP가 있다.
소켓을 이용할 때도 하부 프로토콜로 TCP를 사용할 것인지 UDP를 사용할 것인지 지정해야 한다.
따라서 소켓을 이용할 때는 소켓의 종류와 통신 방식에 따라 네 가지 통신 유형이 나타난다.
소켓을 이용한 프로그래밍에서는 소켓의 종류와 IP 주소, 포트 번호 등을 지정하기 위한 구조체를 사용한다.
sockaddr_un 구조체는 sys/un.h 파일에 정의되어 있다.
sockaddr_un 구조체에는 주소 페밀리명과 경로명이 항목으로 들어있다.
struct sockaddr_un {
__kernel_sa_family_t sun_family; // AF_UNIX
char sun_path[UNIX_PATH_MAX] // 경로명
주소 페밀리명과 포트 번호, IP 주소가 구조체 항목으로 들어 있다.
struct sockaddr_in {
__kernel_sa_family_t sin_family; // 주소 패밀리명
__be16 sin_port; // 포트 번호
struct in_addr sin_addr; // 인터넷 주소
};
struct in_addr {
__be32 s_addr; // 32비트 주소
컴퓨터에서 정수를 저장하는 방식은 두 가지이다.
각각 바이트를 순서대로 저장하는 빅 엔디언과 거꾸로 저장하는 리틀 엔디언이다.
빅 엔디언 방식은 메모리의 낮은 주소에 정수의 첫 바이트를 위치시킨다.
리틀 엔디언 방식은 메모리의 높은 주소에 정수의 첫 바이트를 위치시킨다.
TCP/IP에서는 데이터를 전송할 때 빅 엔디언을 사용한다.
이를 네트워크 바이트 순서 (NBO, Network Byte Order)라고 한다.
반면 호스트에서 사용하는 바이트 순서는
호스트 바이트 순서 (HBO, Host Byte Order)라고 한다.
시스템에서 통신을 통해 데이터를 내보낼 때는 HBO에서 NBO로 데이터순서를 바꿔서 전송하고, 데이터를 받으면 NBO에서 HBO로 변환 후 처리해야 한다.
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); // 호스트 바이트 순서로 저장된 값
uint16_t hrons(uint16_t hostshort); // 호스트 바이트 순서로 저장된 값
uint32_t ntohl(uint32_t netlong); // 네트워크 바이트 순서로 저장된 값
uint16_t ntohs(uint16_t netshort); // 네트워크 바이트 순서로 저장된 값
IP 주소는 192.168.100.1 과 같이 점 ( . ) 으로 구분되는 형태이다.
이진값과 문자영로 표시되는 IP 주소를 서로 변환할 수 있는 함수를 제공한다.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp);
*cp : 문자열 형태의 IP 주소
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
char *inet_ntoa(const struct in_addr in);
in : in_addr 구조체 형태의 ip 주소
inet_ntoa() 함수는 IP 주소를 in_addr 구조체 형태로 받아 점으로 구분된 문자열로 리턴
소켓도 특수 파일의 하나
소켓을 이용해 네트워크 프로그래밍을 할때는 소켓을 생성해 IP 주소와 연결한 후 서버와 클라이언트가 연결되면 소켓을 통해 읽고 쓰면 됨
소켓을 이용해 네트워크 프로그래밍을 할 때 필요한 함수
이 중에서 bind, listen, accept 함수는 서버 측에서만 사용하고, connect 함수는 클라이언트 측에서만 사용한다.
나머지 함수는 클라이언트에서 모두 사용한다.