int socket ( int domain, int type, int protocol )
Q : 전화를 받으려면 뭐가 필요한가요 ?
A : 전화기요
int bind( int sockfd, struct sockaddr *myaddr, socklen_t addrlen )
Q : 당신의 전화번호는요 ?
A : 제 번호는 000 - 0000 입니당.
int listen( int sockfd, int backlog )
Q : 이제 전화기 연결만 하면 되나요 ?
A : 네 연결만 하면 전화를 할 수 있어요
int accept( int sockfd, struct sockaddr *addr, socklen_t *addrlen )
Q : 벨이 울리는데, 어쩌죠
A : 전화를 받으세요
다들 성공하면 0, 실패하면 -1을 반환한다.
socket 빼고 ! socket 은 성공시 파일 디스크립터를 반환한다.
암기할 부분이 있는가 ?
A : 없으면 섭섭하죠
serv_sock = socket( PF_INET, SOCK_STREAM, 0 );
// 소켓을 생성
memset( &serv_addr, 0, sizeof( serv_addr ));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
serv_addr.sin_port = htons(atoi(argv[1]));
// 소켓 초기화
// htonl 데이터를 네트워크 바이트 순서로
// htons 호스트 바이트순서를 네트워크 바이트 순서로 하는 함수라고한다.
// 이과정은 서버소켓과 클라이언트 소켓 모두 동일하게 진행된다.
// 소켓은 만들어지자마자 서버, 클라이언트로 나눠지는게아니고
// 소켓 생성 후, 초기화 까지 한 다음에
// bind, listen 이 호출되면 서버 소켓인 것이고
// connect 가 수행되면 클라이언트 소켓인 것이다.
// 이부분은 내가 만들 소켓의 특성에 따라 바뀔 수 있다.
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
// bind 를 통해 IP 주소와 PORT 번호를 할당
listen(serv_sock, 5);
// 이로써, 소켓은 연결요청을 받아들일 수 있는 상태가 됨
cint_addr_size = sizeof(cint_addr);
cint_sock = accept(serv_sock, (struct sockaddr*)&cint_addr, &cint_addr_size);
// 요청 받아들임 !
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
// 연결을 요청한다.
프로토콜이란 무엇인가
버스터콜 비슷한건가
" 컴퓨터 상호간의 대화에 필요한 통신규약 " 이라고 정리할수 있다.
쉽게 말해 약속이다. 서로 데이터를 주고 받기 위해 미리 정해놓은 약속을 뜻한다.
int socket ( int domain, int type, int protocol )
Q : 왜 이친구가 다시나오나요 ?
A : 누가 물어봤을 때 소켓은 전화기만드는 함수입니다. 라고 할겁니까 ?
Q : 네
Domain : 소켓이 사용할 프로토콜 체계 정보 전달. 우린 PF_INET 을 사용한다.
Type : 소켓의 데이터 전송방식에 대한 정보 전달. 우린 SOCK_STREAM 을 사용한다
Protocol : 두 컴퓨터간 통신에 사용되는 프로토콜 정보전달. 0 으로하면 알아서 잘 해준다. ㄱㅇㄷ
PF_INET 이란 IPv4 인터넷 프로토콜 체계를 의미한다.
SOCK_STREAM 이친군 뭐하는 친구인가요
A : 연결지향형 소켓.. 다른이름으론 TCP 라고도 하죠
연결 지향형 컨베이어 벨트에 A 가 힘차게 최선을 다해 구슬을 만들어 보내고 있다.
10개, 8개, 7개, 14개 .... 그걸 받는 Q 는 그걸 규격 상자에 정확히 10개 씩 담아서 보내고있다.
이 방식의 특징은 다음과 같다.
- 중간에 데이터가 소멸되지 않고 목적지로 전송된다 ( 신뢰성 )
- 전송 순서대로 데이터가 수신된다.
- 전송되는 데이터의 경계 ( Boundary ) 가 존재하지 않는다.
이러한 것이 가능하다
3,4, 번에 걸쳐 write 를 통해 총 100 바이트를 전송하였는데 수신측에서 1번의 read 로 다 읽어갔다.
즉 read 함수 호출횟수와 write 함수 호출 횟수는 별의미가 없다는 뜻 내부 버퍼가 꽉 차지 않는한 write 를 신나게 호출해서 채워 넣어갈 수 있고, 데이터가 수신되었다고 무조건 read 로 다가져갈 필요도 없고 여러번에 나눠서 가져올 수도 있다는 뜻
연결 지향형 소켓 즉 TCP 방식에서 가장 중요한 것은
반드시 소켓 - 소켓의 연결은 1 : 1 이고 신뢰성있는 순차적 바이트 기반의 연결지향 데이터 전송방식
이라고 정리 할 수 있겠다. ( 1명에서 1명으로 전달되는 컨바이어 벨트를 생각하자 )
SOCK_DGRAM 이친군 뭐하는 친구인가요
A : 비 연결지향형 소켓.. 다른이름으론 UCP 라고도 하죠
퀵서비스를 생각하면 됩니다 !
전송된 순서에 상관없이 가장 빠른 전송을 지향하구요
빠르다 보니 전송된 데이터의 손실우려가 있고 파손의 우려도 있습니다.
퀵이 가고있는데 중간에 물건을 실을수 있나요 전송되는 데이터에는 경계가 존재합니다.
퀵에 이삿짐을 실을 순 없죠 데이터의 크기가 제한됩니다 !
UDP 는 이렇듯 퀵서비스를 생각해보자.
수령하는것 역시 마찬가지이다. 퀵이 와서 물건받으라고 하는데 " 두번에 걸쳐서 받을게요 " 라고 할순 없다.
아마 뺨맞을거다
Q : 어...그래서 우리가 쓰는 소켓이 뭐라구요 ?
A : socket( PF_INET, SOCK_STREAM, 0 ) 입니다.
Q : 그게 뭔데요
A : IPv4 방식에 TCP 프로토콜을 사용하는 소켓 이라구 이 멍청아!
Q : 그런데 TCP 는 그래서 어떤 친구라고 했죠 ?
A : 1:1 방식으로 데이터의 경계가 없는 연결지향형 프로토콜이라고요...컨베이어 벨트를 생각해
Q: 그럼 UDP 는요
A : 누구보다 빠른 퀵 서비스 !