티스토리 뷰
#include <sys/types.h>
c언어의 버전이 업 되면서 변경된 자료형의 정의들과
시스템마다 int를 표현하는 바이트수가 다르므로 그런것들을 다른 자료형으로 정의하는 typedef문들이 들어있다.
(int가 어떤곳에선 2바이트 , 요즘에는 거의다 4바이트이기 때문에 이 두개의 자료형을 구분하는 어떤 타입정의가 필요함)
한마디로 시스템에서 사용하는 자료형에 관한 정보들을 담고있다.
#include <netinet/in.h>에 정의된 소켓 구조체
struct sockaddr_in
{
unsigned short int sin_family; //16비트
uint_16t sin_port; //16비트
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
socket(AF_INET, SOCK_STREAM,0)
AF_INET과 PF_INET은 동일하다.
또한 AF_INET(ipv4프로토콜체계를 사용하겠다)와 SOCK_STREAM(연결지향형 소켓을 생성하겠다)의 의미로 충분히 소켓에 대한 정보를 제공했다고 생각할 수 있으나, ipV4에서 동작하며 연결지향형인 프로토콜은 사실 TCP이외에도 SCTP와 같은 프로토콜도 존재한다 따라서 마지막 인자를 통해서 정확히 어떤 프로토콜을 사용할것인지 구체적으로 명시하는것이다.
AF_INET -> 상대방의 응용프로그램과 통신하기 위한 조건 (Address family_internet) 주소 가족이 인터넷프로토콜이다.
동일한 주소체계, 동일 프로토콜 -> 인터넷 프로토콜을 사용해서 통신하겠다.
SOCK_STREAM
소켓의 종류
연결성 소켓(Stream socket) - TCP처럼 연결형 서비스를 지원하는 프로토콜을 사용할때 소켓은 연결성 소켓을 사용해야한다.
비연결성 소켓(Datagram socket) - UDP처럼 비연결형 서비스를 지원하는 프로토콜을 사용할때는 비연결성 소켓인 SOCK_DGRAM사용
로 소켓(Raw socket)
- 응용프로그램에서 Layer4인 전송계층을 거치지 않고 바로 Layer3인 네트워크 계층에 어떤 명령을 내리는 소켓을 사용하고 싶을때
- SOCK_RAW
패킷 소켓(packet socket)
- 응용프로그램에서 Layer2인 데이터링크 계층(랜카드,이더넷)으로 바로 명령을 내리고 싶을때 (그사이의 계층들을 거치지 않고 바로)
- SOCK_PACKET
하위계층 프로토콜
0: 디폴트 프로토콜
응용프로그램이 Layer4에 있는 프로토콜중 어떤것을 선택할것인지 에 대한 매개변수
<sys/socket.h> 헤더파일에 정의된 소켓의 종류 (번호로 소켓의 종류를 구분함)
SOCK_STREAM == 1
SOCK_DGRAM == 2
SOCK_RAW == 3
SOCK_PACKET == 10 번으로 정의 되어 있음.
소켓의 하위계층 디폴트 프로토콜 - 소켓의 하위계층 프로토콜을 어떤걸로 사용할것인지 숫자로 표현
<netinet/in.h>에 정의 되어 있음.
Stream Socket
TCP
IPPROTO_TCP == 6번으로 정의
Datagram Socket
UDP
IPPROTO_UDP == 17번으로 정의
Raw Socket
IPPROTO_RAW == 255번으로 정의
Packet Socket
<linux/if_ether.h>에 정의되어 있음.
ETH_P_ALL -> 이더넷에서 모든 패킷을 가져 오겠다.
ETH_P_IP -> 이더넷에서 IP에 관한것만 뽑아오겠다.
ETH_P_ARP -> 이더넷에서 ARP(Address Resolution protocol)에 관한것만 뽑아오겠다.
ETH_P_IPV6 -> 이더넷에서 IPv6에 관한것만 뽑아 오겠다.
하위 계층 프로토콜에 0번을 사용하겠다는것은 디폴트 프로토콜을 사용하겠다는 뜻
-> sockfd = socket(AF_INET,SOCK_STREAM,0);
-> 앞에 매개변수로 SOCK_STREAM을 적었으므로 이에 해당하는 디폴트 프로토콜은 TCP프로토콜(IPPROTO_TCP == 6)이다.
-> 만약에 앞에 매개변수로 SOCK_DGREAM이 적혀 있었다면 디폴트 프로토콜은 UDP프로토콜(IPPROTO_UDP==17)이 될 것이다.
-> 즉 맨 마지막에 0대신에 TCP/UDP에 따라서 6이나 17을 넣어도 동작한다는 뜻.
-> 그러니까 원래는 6이나 17을 입력해야 동작하지만 0을 입력해도 알아서 프로토콜을 찾아줌.
socket()시스템콜은 보통 소켓을 생성하면 3번을 리턴하기때문에 sockfd에는 3번이 들어감.
<string.h>에 있는 bzero 함수를 통해서 소켓 구조체를 전부 0 으로 초기화 시킴.bit zero라는 의미
bzero( (char*) &serv_addr, sizeof(serv_addr));
serv_addr에는 sin_family,sin_port,sin_addr,sin_zero[8] 등의 정보가 저장된 소켓 구조체
sock() 시스템 콜을 통해서 소켓을 생성하고 나면 그 소켓을 전세계에서 유일하게 식별할수 있는 이름을 지어주어야 한다.
그래야 클라이언트에서 오지에 있는 서버의 어떤 응용 프로세스와 통신을 할 수 있다.
그 이름을 지어주는것이 bind()라는 시스템 콜이다.
우리가 아까 만들었던 소켓 구조체는 출생 신고서에 비유 할 수있다.
<<-출생 신고서
즉 Application Family는 인터넷 프로토콜을 사용하고 아이피 주소는 200.100.50.20이며 포트번호는 8888인 소켓이다.
아이피 주소라는것을 통해서 전세계에서 어떤 네트워크나 호스트를 유일하게 식별할 수 있고, 포트번호를 통해 유일하게 식별된 호스트에서의
여러 응용프로그램들 중 어떤 하나의 프로그램을 유일하게 지칭할 수 있다.
그렇기 때문에 위의 소켓 구조체의 내용으로 우리는 전세계에서 유일하게 식별 가능한 어떤 소켓의 신고서를 만든 것이다.
신고서를 만들었으면 구청에 등록을 해야겠다.
그게 바로 bind() 시스템 콜이다.
현실 세계라면 구청에 출생신고를 하겠지만 컴퓨터세계에서는 운영체제가 구청의 역할을 맡는다.
즉 전세계에서 유일하게 구별된 소켓의 정보를 아까 생성한 소켓에 붙이는것이다. (아이가 태어났고 그 아이의 이름을 지어주는 개념)
bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr));
아까 생성했던 소켓(sockfd = 소켓번호)에 그 소켓에 대한 정보를 담은 구조체(전세계에서 유일함,serv_addr)를 연결해서 운영체제에 알려주겠다.
-> 태어난 아이에게 이름,나이,주민번호를 구청에 할당하는것과 같은 이치.
htonl -> 바이트의 순서를 바꿔주는 시스템콜. 네트워크 표준은 빅엔디안을 사용하고 컴퓨터에서는 리틀엔디안을 사용할 수 도있으므로
네트워크를 통해 패킷을 보낼 땐 빅엔디안으로 항상 변경해주어야 한다.
리틀엔디안이라는 것은 MSB가 맨 왼쪽에 있는 바이트 순서이고 빅 엔디안은 MSB가 맨 오른쪽에 있는 바이트 순서이다.
-> 한마디로 패킷을 받을때 어디가 머리냐 어디가 꼬리냐를 정하는것.
INADDR_ANY
서버에는 랜카드가 여러개가 있을 수 있다. 그럼 그 랜카드 마다 할당된 이더넷 주소가 여러개 있을 것이고 또 그 여러개의 이더넷 주소에 해당하는 아이피 주소가 여러개일것이다. 즉 한 컴퓨터가 여러개의 아이피 주소를 가질 수 있다.
내가 가진 어떤 아이피 주소로 패킷이 들어오더라도 나는 그것을 다 처리하겠다는 뜻이 INADDR_ANY이다.
이 값은 <netinet/in.h>에 #define INADDR_ANY 0x00000000 로 정의 되어 있다. 16진수 1비트는 2진수 4비트로 치환되므로 4*8 = 32비트 = 4바이트가 모두 0인것으로 정의 되어 있는 것이다.
IPv4에서 아이피를 4바이트로 나타내는데 4바이트가 모두 0인경우 자신의 아이피 주소를 나타낸다.
즉, 내가 가진 아이피주소가 여러개가 있을 수 있는데 그 중 아무거나 쓰겠다는 뜻이다.
listen() 동시 접속설정 요청 대기 수
listen(sockfd,5);
-> 소켓에 대한 연결 설정 요청의 대기 큐 사이즈가 5이다.
즉 sockfd에 해당하는 소켓에 연결 설정 요청 할 수 있는 클라이언트는 5개까지가 최대이다.
'컴퓨터 공학과 졸업 > 소켓 프로그래밍' 카테고리의 다른 글
connect() 시스템콜 에러상황 (1) | 2017.09.23 |
---|---|
Listen Socket and Connected Socket (0) | 2017.09.21 |
서버 프로그램 포트번호 사용시 주의사항 (0) | 2017.09.15 |
소켓프로그래밍 서버 프로그램 작성 (0) | 2017.09.15 |
소켓 프로그래밍(daytime) 클라이언트 프로그램 (0) | 2017.09.13 |
- Total
- Today
- Yesterday
- Action
- state
- server side rendering
- typescript
- promise
- es6
- Next.js
- javascript
- useEffect
- useRef
- storybook
- reactdom
- async
- Babel
- type alias
- react
- reflow
- rendering scope
- return type
- mobx
- props
- await
- react hooks
- computed
- hydrate
- atomic design
- reducer
- webpack
- Polyfill
- design system
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |