프로토콜의 이해와 소켓의 생성
프로토콜이란?
- 개념적으로 약속의 의미를 담고 있다.
- 컴퓨터 상호 간의 데이터 송수싱네 필요한 통신 규약.
- 소켓을 생성할 때 기본적인 프로토콜을 지정해야한다.
#include <sys/socket.h> int socket(int domain, int type, int protocol); |
-> 성공시 파일 디스크립터, 실패 시 -1 반환
- domain 소켓이 사용할 프로토콜 체계(Protocol Family) 정보 전달.
- type 소켓의 데이터 전송방식에 대한 정보 전달.
- protocol 두 컴퓨터 간 통신에 사용되는 프로토콜 정보 전달.
프로토콜 체계(Protocol Family)
프로토콜 체계
- 프로토콜도 그 종류에 따라서 부류가 나뉘는데, 그 부류를 가리켜 프로토콜 체계라 한다.
- 프로토콜의 체계 PF_INET은 IPv4인터넷 프로토콜 체계를 의미한다. 우리는 이를 기반으로 소켓 프로그래밍을 학습한다.
이름 |
프로토콜 체계(Protocol Family) |
PF_INET |
IPv4 인터넷 프로토콜 체계 |
PF_INET6 |
IPv6 인터넷 프로토콜 체계 |
PF_LOCAL |
로컬 통신을 위한 UNIX 프로토콜 체계 |
PF_PACKET |
Low Level 소켓을 위한 프로토콜 체계 |
PF_IPX |
IPX 노벨 프로토콜 체계 |
소켓의 타입(Type)
소켓의 타입
- 데이터 전송방식을 의미함.
- 소켓이 생성될 때 소켓의 타입도 결정되어야 한다.
프로토콜 체계 PF_INET의 대표적인 소켓 타입 둘
- 연결 지향형 소켓 타입
- 비 연결 지향형 소켓 타입.
연결지향형 소켓(SOCK_STREAM)의 데이터 전송 특성
- 중간에 데이터 소멸되지 않는다.
- 전송 순서대로 데이터가 수신된다.
- 데이터의 경계가 존재하지 않는다.
- 소켓 대 소켓의 연결은 반드시 1대 1의 구조.
비 연결지향형 소켓(SOCK_DGRAM)의 데이터 전송특성
- 전송순서 상관없이 빠른 속도의 전송을 지향
- 데이터 손실 및 파손의 우려있다.
- 데이터의 경계가 존재한다.
- 한번에 전송할 수 있는 데이터의 크기가 제한된다.
프로토콜의 최종 선택
TCP 소켓
int tcp_socket= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); |
UDP
int udp_socket= socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
-> 첫 번째, 두번재 인자로 전달된 정보를 통해서 소켓의 프로토콜이 사실상 결정 되기 때문에 세번재 인자로 0을 전달해도된다.
tcp_server.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> void error_handling(char *message); int main(int argc, char *argv[]) { int serv_sock; int clnt_sock; struct sockaddr_in serv_addr; struct sockaddr_in clnt_addr; socklen_t clnt_addr_size; char message[]="Hello World!";
if(argc!=2){ printf("Usage : %s <port>\n", argv[0]); exit(1); }
serv_sock=socket(PF_INET, SOCK_STREAM, 0); if(serv_sock == -1) error_handling("socket() error");
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]));
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) error_handling("bind() error");
if(listen(serv_sock, 5)==-1) error_handling("listen() error");
clnt_addr_size=sizeof(clnt_addr); clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size); if(clnt_sock==-1) error_handling("accept() error");
write(clnt_sock, message, sizeof(message)); close(clnt_sock); close(serv_sock); return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } |
tcp_client.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> void error_handling(char *message); int main(int argc, char* argv[]) { int sock; struct sockaddr_in serv_addr; char message[30]; int str_len=0; int idx=0, read_len=0;
if(argc!=3){ printf("Usage : %s <IP> <port>\n", argv[0]); exit(1); }
sock=socket(PF_INET, SOCK_STREAM, 0); if(sock == -1) error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=inet_addr(argv[1]); serv_addr.sin_port=htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) error_handling("connect() error!"); while(read_len=read(sock, &message[idx++], 1)) { if(read_len==-1) error_handling("read() error!");
str_len+=read_len; } printf("Message from server: %s \n", message); printf("Function read call count: %d \n", str_len); close(sock); return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } |
'이전것 > 네트워크' 카테고리의 다른 글
4.1. TCP, UDP (0) | 2016.12.01 |
---|---|
3.2. 주소 정보의 표현 (0) | 2016.12.01 |
3.1. 소켓에 할당되는 IP주소와 PORT 번호 (0) | 2016.12.01 |
1.1. 네트워크 프로그래밍과 소켓의 이해 (0) | 2016.11.15 |
Java->NETWORK -> http://blog.naver.com/cyberhole/110133796455 (0) | 2016.11.04 |