2011년6월29일_소켓통신의 흐름과 TCP/IP통신 예제코드 첫 부분 분석

 

● 소켓통신의 흐름

 

● socket( )의 원형

     int socket(int domain, int type, int protocol);
   ④반환값                  ①프로토콜 패밀리      ②소켓형식         ③프로토콜

① 프로토콜 패밀리 ┬ PF_INET : IPv4인터넷
                        ┣ PF_INET6 : IPv6 인터넷 프로토콜 체계
                        └ PF_UNIX : 유닉스
                           ※ PF(프로토콜 패밀리) ≒ AF(어드레스 패밀리)
② 소켓형식 ┬ SOCK_STREAM : TCP형 소켓을 만들겠다.
               └ SOCK_DGRAM : UDP형 소켓을 만들겠다.
③ 프로토콜 ┬ IPPROTO_TCP : TCP
               └ IPPROTO_UDP : UDP
④ 반환값 ┬ 성공 : 음수가 아닌 값 (3, 4, 5…)
            └ 실패 : –1

소켓형식과 프로토콜은 TCP형이면 TCP, UDP형이면 UDP로 같게 되므로,
소켓형식에 SOCK_STREAM을 넣은 뒤 프로토콜에 0을 넣으면 소켓형식에 맞춰 TCP protocol로 맞춰진다.

 

● 주소지정


● 범용 구조체

struct sockaddr {                 // 구조체 전체크기는 16Bytes
    sa_family_t sa_family;     // 패밀리는 unsigned short형 
    char sa_data[14];           // IP주소 4Bytes + Port번호 2Bytes (총 6Bytes)
} ;


sa_data[0]과 sa_data[1]에는 포트번호가 들어가고 sa_data[2] ~ sa_data[5]에는 IP주소가 들어간다.

● IPv4 주소용 구조체

struct sockaddr_in {          //sockaddr과 마찬가지로 16Bytes
    sa_family_t sin_family;    //주소패밀리
    in_port_t sin_port;        // 포트번호
    struct in_addr sin_addr;   //IP주소
    char sin_zero[8];          // sockaddr과 호환을 위한 더미
};


범용과 다른 점은 IP주소와 포트번호가 따로 나뉘어져 있다는 것이다.
IP주소를 담는 in_addr구조체는 아래와 같이,

struct in_addr {
    uint32_t s_addr;     //인터넷주소32bit
};


unsigned int형으로 4Bytes 자료형으로 선언되어 있다.
IP주소의 최대값은 255.255.255.255이니 각 자리가 1Byte씩 총 4Bytes(32bit)인 것이다.

 

● helloworld_server.c 코드 분석

17행: struct  sockaddr_in  serv_addr; 
                구조체           자료형                변수명

serv_addr변수를 sockaddr_in자료형으로 구조체선언.

 

23행: serv_sock = socket(PF_INET, SOCK_STREAM, 0);
            -1이면 에러처리(예외처리)                  IPv4                     TCP                 TCP

client도 마찬가지로 TCP프로토콜 소켓 인스턴스를 생성.


30행: memset(&serv_addr, 0, sizeof(serv_addr));
                                     대상주소         채울 값         몇 바이트 채울지

serv_addr구조체를 0으로 초기화함.

31행: serv_addr.sin_family = AF_INET;
                       프로토콜패밀리                       IPv4주소체계

4Bytes IP주소와 2Bytes 포트번호를 사용하는 주소체계로 설정.

 

32행: serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
                                       IP주소                                              localhost 

INADDR_ANY에 대해 네이버 검색해보니..
localhost이고 자신의 IP가 아닌 0x0000으로 되어 있다가 클라이언트가 connect( )로 요청하면 클라이언트IP로 바뀐다?
그래서 구글에서 검색하니…
어떤 IP주소의 클라이언트가 접속하여도 연결할 수 있게 하고 싶을 때 쓴다고 한다.

클라이언트측 IP는 서버의 IP를 입력하면 된다.
PC 한 대로 시험할 때는 loopback주소 “127.0.0.1”  localhost도 “127.0.0.1”로 정의되어 있단다.


33행: serv_addr.sin_port = htons(9190);
                              포트번호                             

포트번호를 9190으로 한다.