소켓이란 네트워크 프로그램을 개발할 수 있도록 운영체제에서 제공하는 인터페이스라고 표현할 수 있다. 즉 네트워크를 통해 데이터 패킷을 주고 받는 개체인 통신 종점이다.    

일반적으로 우리가 사용하는 소켓은 BSD소켓이다 
BSD 소켓은 네트워크 프로그램을 개발하기 위한 함수 및 라이브러리 등을 포함하고 있고 대부분의 네트워크 프로그램이 소켓 관련 라이브러리를 사용하여 개발된다.

리눅스를 포함함 유닉스 등의 POSLX 계열의 운영체제는 대부분 BSD 소켓을 원형 그대로 지원하고 있지만, 윈도우 소켓은 BSD 소켓을 기반으로 일부 고유 기능을 수정, 확장하여 제공함

소켓은 크게 2가지 형태로 사용할 수 있다


첫 번째 형태는 스트림 소켓이다


스트림 소켓은 데이터를 구분하는 레코드의 경계 없이 바이트 스트림인 데이터를 송수신하며 , 정확하게 순차적이고 중복되지 않는 전달을 보장한다.
전송 프로토콜로는 TCP를 사용한다.

두 번째 형태는 데이터그램 소켓이다.

데이터그램 소켓은 전달이 보장되지 않으며 순차적이지 않거나 중복될 수 있는 레코드 기반으로 데이터를 송수신한다.
데이터그램 , 소켓에 사용되는 전송 프로토콜로는 UDP를 사용한다.

---------------------------------------------------------------------------------------------

소켓 관련 함수 

1
2
3
4
5
6
7
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>
#endif
int socket(int domain, int type, int protocol);

cs

socket() 함수는 소켓을 초기화하는 함수이다

첫 번째 인자는 통신 도메인을 지정하는 인자로 어떤 네트워크에서 사용될 소켓인지 지정하는 인자이다 .
소켓은 TCP/IP 인터넷 망에서 사용될 수 있을 뿐만 아니라 다른 망에서도 함께 사용될 수 있다.
첫 번째 인자를 통해서 어떤 망에서 사용될 소켓인지 지정할 수 있다.

두 번째 인자는 스트림을 의미하는 SOCK_STREAM이 존재하고 데이터그램을 의미하는 SOCK_DGRAM이 있다. 
프로토콜 헤더를 직접 만들 필요가 있는 경우에는 SOCK_RAW을 사용한다.
RAW소켓은 특별한 형태의 패킷을 만들어서 전송할 수 있을 뿐만 아니라 다른 어플리케이션이 송수신하는 네트워크 패킷의 데이터를 함께 확인할 수 있다
윈도우에서는 RAW 소켓을 지원하지 않고 리눅스에서는 root권한 으로만 실행이 가능하다.

세 번째 인자는 어떤 통신 프로토콜을 사용할 것인지 지정하는 것으로 정상적으로 생성이되면 각각의 소켓을 구분할 수 있는 소켓 디스크립터가 리턴되며 , 소켓을 생성하는 과정중에서 에러가 발생하면 0 혹은 0 이하의 수가 반환이 된다 .

connect() 함수

1
2
3
4
5
6
7
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/type.h>
    #include <sys/socket.h>
#endif
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
cs

connect() 함수는 연결 대기 중인 서버로 실제 연결을 맺는 함수다.
소켓을 생성할때 SOCK_STREAM으로 생성된 경우에 클라이언트에서 서버에 접속하기 위하여 사용하는 함수다.

첫 번째 인자는 socket 함수를 호출한 뒤에 리턴되는 소켓 디스크립터를 지정한다

두 번째 인자는 접속하고자 하는 아이피 및 서버 포트 정보가 있는 sockaddr 구조체의 주소값을 지정한다 ( 서버 주소 정보 )

세 번쨰 인자는 sockaddr *addr 포인터가 가리키는 구조체의 크기를 TCP/IP의 실제 주소 정보를 저장하기 위해서는 sockaddr_in 구조체가 사용된다

sockaddr_in의 구조체는 아래와 같이 이루어져있다

1
2
3
4
5
6
 struct sockaddr_in{
   short sin_family;
   unsigned short sin_port;
   struct in_addr sin_addr;
   char sin_zero[8];
};
cs

sin_family : 주소 패밀리(AF_INET이여야 한다.)
sin_port   : UDP , TCP 프로토콜에서 사용되는 포트 주소값을 저장한다
sin_addr  : IP 주소값을 저장하기 위한 멤버 변수 , 주소를 저장할 수 있는 구조체 in_addr을 사용한다
sin_Zero  : sockaddr 구조체와 같은 크기를 유지하기 위해서 필요한 패딩 공간이며 항상 0이 저장되있어야 한다.

in_addr 구조체는 멤버를 단 한 개를 갖고 있으며 4바이트 크기의 변수 s_addr을 갖는 구조체이다.

1
2
3
4
5
typedef uint32_t in_addr_t;
struct in_addr
{
    in_addr_t s_addr;
};

connect() 함수를 호출한 뒤에는 서버와의 연결이 성공적으로 이뤄지게 되면 0을 리턴하고 연결에 실패하면 0보다 작은 값을 리턴한다.


bind() 함수

1
2
3
4
5
6
7
8
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>
#endif
 
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
cs


bind() 함수는 서버에서 소켓 연결에 사용되는 주소를 소켓에 할당하기 위해서 사용되는 함수.

첫 번째 인자는 소켓을 생성한 후 리턴되는 소켓 디스크립터이다.
두 번쨰 인자는 sockaddr 구조체의 주소값
세 번째 인자는 sockaddr *addr 포인터가 가리키는 구조체의 길이.

bind() 함수에서는 connect() 함수와는 달리 소켓 디스크립터에 할당하는 즉 연결받고자 하는 주소값이 저장된 sockaddr 구조체의 주소값이다 .

(연결을 하는 입장인지 받는 입장인지 봐야할 것)

[출처 : http://forum.falinux.com/zbxe/index.php?document_srl=438301&mid=C_LIB]


listen() 함수 

1
2
3
4
5
6
7
8
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>
#endif
 
int listen(int sockfd, int backlog);
cs

listen() 함수는 해당 소켓에서 연결을 기다리는 함수다
첫 번째 인자는 소켓을 생성한 뒤에 리턴되는 소켓 디스크립터이다.
두 번째 인자는 연결을 기다리는 대기열 큐의 사이즈이다.


accept() 함수

1
2
3
4
5
6
7
8
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>
#endif
 
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
cs

accept() 함수는 해당 소켓에 연결 요청이 왔을 때 연결을 받아들이는 함수이다.
연결이 성공적으로 이루어졌을때 리턴 되는 값은 연결을 받아들인 새로운 소켓 이며 연결에 실패했을때는 0 아니면 0 이하의 수를 리턴한다 .

첫 번째 인자는 소켓 디스크립터이다
두 번쩨 인자는 클라이언트의 주소 정보 정보가 저장될 구조체의 주소값이다.
세 번째 인자는 sockaddr 구조체의 길이가 저장된 변수의 주소값이다.

해당 소켓으로서 연결 요청이 없는 경우에는 클라이언트가 연결을 요청할 때까지 소켓을 계속 감시하면서 대기 상태를 유지하게 된다.


send() 함수

1
2
3
4
5
6
7
8
#ifndef __linux__
    #include <winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>
#endif
 
ssize_t send(int sokcfd, const void *buf, size_t len, int flags);
cs

SOCK_STREAM으로 생성된 소켓에서 데이터를 수신받기 위한 함수다

첫 번째 인자 : 소켓 디스크립터
두 번째 인자 : 보내고자 하는 데이터의 시작 주소값
세 번째 인자 : 데이터의 시작 주소부터 끝까지의 길이
네 번째 인자 : -1 이외 : 실제 전송한 바이트수 -1 :실패

'네트워크' 카테고리의 다른 글

와이파이 에어 크랙  (0) 2017.01.09
TCP 서버 예제  (0) 2016.08.12
클라이언트와 서버  (0) 2016.08.11
네트워크 서비스  (0) 2016.08.11
프로토콜  (0) 2016.08.11

+ Recent posts