본문 바로가기
2023-1/컴퓨터네트워크및실습

Socket Basic (실습)

by 철없는민물장어 2023. 3. 17.
728x90
반응형

Network Programming(Socket Programming)

 

소켓은 컴퓨터 네트워크에서 프로세스 간 통신을 가능하게하는 기술이며, 네트워크상에서 데이터 송수신을 담당한다.

 

소켓은 주로 클라이언트/서버 모델에서 사용되며, 클라이언트는 서버로 연결을 시도하고, 서버는 연결을 수락하고 데이터를 송수신한다. 

소켓은 application 레이어와 transport레이어 사이의 인터페이스 역할을 한다.

 


서버측 주요코드
#include <sys/socket.h>

int socket(int domain,int type, int protocol); //성공시 파일 디스크립터를, 실패시 -1 반환

int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);//IP와 포트번호를 소켓에 할당

int listen(int sockfd, int backlog); //성공시 0, 실패시 -1 반환

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //성공시 파일 디스크립터, 실패시-1 반환. 
//socket함수의 리턴 파일 디스크립터는 접속요청용, accept의 리턴 파일 디스크립터는 데이터 송수신용

 

int socket(int domain, int type, int protocol)

domain: 소켓이 사용할 프로토콜 체계(protocol family)이다. (IPv4를 사용하는지, IPv6인지.. 등. IPv4는 PF_INET이다.)

type: 소켓의 데이터 전송방식이다. 연결지향형(connection oriented)인지, 비연결지향형(connectless)인지 적어주어야 한다. 연결지향형은 SOCK_STREAM을 넘기면 되고, 비연결지향형은 SOCK_DGRAM을 넘기면 된다.

protocol: 두 컴퓨터간 통신에 사용되는 프로토콜 정보이다. TCP인 경우 IPPROTO_TCP를, UDP인 경우 IPPROTO_UDP를 넘기면 된다. 그런데, 앞서 type에 적은 정보를 통해 소켓의 프로토콜이 정해지기 때문에 protocol에 0을 전달해도 된다.

성공시 파일디스크립터를, 실패시 -1을 반환한다

 

int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen)

IP와 포트번호를 소켓에 할당하는 함수.

sockfd: 주소정보(IP와 PORT)를 할당한 소켓의 파일 디스크립터이다. socket()으로부터 반환받은 파일 디스크립터를 넣어주면 된다.

myaddr: 할당하고자 하는 주소정보를 지니는 구조체 변수의 주소 값

일반적으로 bind함수 사용시

bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1)
	error_handling("bind() error");

위와 작성하게 되는데,

두번 째 인자가 *myaddr 이다.

그런데, sockaddr 포인터 타입을 바로 전달하는 것이 아니라, sockaddr_in 타입의 serv_addr를 작성한 뒤에, 형변환하여 전달하고 있다. 왜 이렇게 복잡하게 했을까?

 

우선 sockaddr의 구조를 보면

struct sockaddr
{
	sa_family_t sin_family; //주소체계(address Family. IPv4인지..v6인지..)
    char sa_data[14]; //주소정보
}

위와 같은데,

sa_data라는 14바이트의 배열안에 port번호, IP주소, 나머지 빈칸은 0으로 채워야 한다.

그런데, 개발자가 이 배열에 일일이 차곡차곡 작성하고 있기는 힘들기 때문에 sockaddr_in 구조체를 만들어 작성하고, sockaddr으로 변환하여 사용하는 것이다

sockaddr_in의 구조는 아래와 같다.

struct sockaddr_in
{
	sa_family_t sin_family; //주소체계
    uint16_t sin_port; //port번호
    struct in_addr sin_addr; //32비트 IP주소
    char sin_zero[8]; //사용되지 않음. 0으로 채움
}

struct in_addr
{
	in_addr_t s_addr; //32비트 IPv4 인터넷주소
}

(참고: 위 sockaddr_in 구조체는 IPv4만을 위한 구조체이다)

sockaddr로 변환하여 사용하기 위해, IPv4를 위한 구조체임에도 sin_family 값을 또 저장하고 있어야 하고

sockaddr에 필요한 port번호, 32비트 IP주소, 0을 가지고 있다.

 

addrlen; 두 번째 인자로 전달된 구조체 변수의 길이정보

 


클라이언트 주요 코드
#include <sys/socket.h>

int socket(int domain, int type, int protocol); //성공시 파일 디스크립터를, 실패시 -1 반환

int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen); //성공시 0, 실패시 -1 반환

 


소켓 통신 과정

 

728x90
반응형

'2023-1 > 컴퓨터네트워크및실습' 카테고리의 다른 글

htons / inet_addr  (0) 2023.03.31
DHCP  (0) 2023.03.23
IP Addressing: classful, CIDR /IP Fragmentation /NAT  (0) 2023.03.17
Network Layer Basic  (0) 2023.03.10
Network Layer  (1) 2023.03.09

댓글