헤더 : <sys/socket.h>

 

<서버>

socket() : 소켓 생성 함수

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

                      -첫번째 매개변수  :  어떤 영역에서 통신할 건지 영역 지정 ( protocol family )

                                                 - AF_INET : ipv4 / AF_INET6 : ipv6

                      -두번째 매개변수 :  어떤 서비스 타입의 소켓을 생성할건지 지정( socket type )

                                                 - SOCK_STREAM : TCP

                                                 - SOCK_DGRAM : UDP

                                                 - SOCK_RAW : TCP,UDP를 거치지 않고 바로 IP 계층 사용

                      -세번째 매개변수 :  소켓에서 사용할 프로토콜 지정

                                                 - IPPROTO_TCP : TCP / IPPROTO_UDP : UDP

                                                 - 0 : socket type에서 이미 정해진 경우

          

           성공     =>       소켓 디스크립터(0 이상)

           실패     =>         -1

 

bind() : 서버의 ip주소와 port를 소켓에 할당해주는 함수

           - clientserver의 소켓 디스크립터번호를 알아야 하기 때문에 사용

 

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

                      -첫번째 매개변수  :  ip,port를 할당해줄 서버 소켓 디스크립터 번호

                      -두번째 매개변수  :  서버의 ip를 담고있는 sockaddr 구조체의 주소값

                      -세번째 매개변수  :  서버정보가 담긴 serv_addr 구조체 길이

          

           성공     =>       0

           실패     =>       -1

 

listen() : client에서 요청이 오면 수락할 수 있도록 대기상태에 들어가는 함수

           int listen(int sockfd, int backlog);

                      -첫번째 매개변수 :  서버 소켓 디스크립터

                      -두번째 매개변수 :  client가 대기할 수 있는 대기열의 크기를 지정

          

           성공     =>       0

           실패     =>       -1

 

accept() : 서버에 client를 연결하는 함수

           int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);

              - 첫번째 매개변수 :  서버 소켓 디스크립터

              - 두번째 매개변수 :  연결된 클라이언트의 ip주소 정보를 담을 sockaddr 구조체 주소

              - 세번째 매개변수 :  연결된 클라이언트 정보가 담길 sockaddr 구조체 길이

 

<클라이언트>

connect() : 서버로 연결요청하는 함수

           int connect(int sockfd, struct sockaddr* serv_addr, socklen_t addrlen);

              - 첫번째 매개변수 :  서버와 통신하기 위한 소켓 디스크립터

              - 두번째 매개변수 :  연결할 서버의 ip,port정보를 담고 있는 sockaddr 구조체 주소

              - 세번째 매개변수 :  연결할 서버의 정보가 담긴 sockaddr 구조체 길이

          

           성공     =>       0

           실패     =>       -1

 

close() : 소켓을 닫고 통신을 종료하는 함수

           -<unistd.h>

           int close(int sockfd);

          

           성공     =>       0

           실패     =>       -1

 

server 구현        =>       client, server소켓 둘 다 생성

client 구현         =>       소켓 1개만 생성

                                 ( 서버의 정보를 담고있는 sockaddr 구조체를 이 소켓에 담음).

                                 ( connect()로 서버와 연결해서 그 때 담는다. )

 

 

<소켓 통신에서 주의사항>

- 소켓을 보낼 때 내가 fgets100까지 읽어오라고 해도, 정확히 100까지 읽는다는 보장 X.

- tcp는 그나마 신뢰성 통신이라 드물긴 하지만, udp인 경우에는 더 드라마틱하게 이상하게 보내질 때가 많음.

  그렇기 때문에 fgets(req_line,100,clnt_read) 같은 형태로 소켓으로부터 데이터를 읽어오도록 해도 100만큼 정확히 읽어 온단 보장이 없기 때문에 조건을 걸어서

  (EX : \r\n을 만나기 전까진 버퍼에서 보내지 말고 버퍼 뒤에 이어붙여라)

  완전히 원하는 만큼 데이터가 보내지도록 개발자가 보장을 직접 해줘야 함.

 

<소켓 통신시 발생하는 문제점>

문제점

      - 전송측은 빅 엔디안으로 전송 / 받는 쪽은 리틀 엔디안으로 처리

         =>서버와 클라이언트의 바이트 정렬 방식이 다르기 때문

 

해결방법

      - 받는 측(리틀 엔디안)에서 전송받은 데이터(빅 엔디안)를 뒤집어서 처리!!

         => 개발자가 해야 할 것 : port번호, ip주소만 직접 처리해주면 됨.

         => 기본적으로 pc는 리틀 엔디안이므로 이를 빅 엔디안으로 변경해야함.

          

        포트  :  2byte로 이루어짐

        IP     :  4byte로 이루어짐

 

+ Recent posts