소켓 생성


socket() 함수는 소켓을 생성하여 반환합니다.

헤더#include <sys/types.h> 
#include <sys/socket.h>
형태int socket(int domain, int type, int protocol);
인수
int domain

: 인터넷을 통해 통신할 지, 같은 시스템 내에서 프로세스 끼리 통신할 지의 여부를 설정합니다.

 
domaindomain 내용
PF_INET, AF_INET

IPv4 인터넷 프로토콜을 사용합니다.

PF_INET6

IPv6 인터넷 프로토콜을 사용합니다.

PF_LOCAL, AF_UNIX같은 시스템 내에서 프로세스 끼리 통신합니다.
PF_PACKETLow level socket 을 인터페이스를 이용합니다.
PF_IPX

IPX 노벨 프로토콜을 사용합니다.

int type: 데이터의 전송 형태를 지정하며 아래와 같은 값을 사용할 수 있습니다. 
typetype 내용
SOCK_STREAM

TCP/IP 프로토콜을 이용합니다.

SOCK_DGRAMUDP/IP 프로토콜을 이용합니다.
int protocol: 통신에 있어 특정 프로토콜을 사용을 지정하기 위한 변수이며, 보통 0 값을 사용합니다.
반환
-1 이외: 소켓 식별자
-1: 실패

TCP/IP 소켓 프로그램을 작성해 보겠습니다.

TCP/IP 통신 함수 사용 순서

domain : 소켓이 사용되는 네트워크의 영역을 정의

다른프로그램끼리 통신하는 것을 IPX 흔히 스타크래프트 할 때 사용된다.


type & protocol

type : 통신에 사용할 패킷의 타입을 지정

protocol : 통신에 사용할 프로토콜 지정

type에 따라서 protocol이 정해짐


SOCK_STREAM & IPPROTO_TCP : TCP기반의 통신에 사용

SOCK_DGRAM & IPPROTO_UDP : UDP기반의 통신에 사용

SOCK_RAW & (원하는 프로토콜) : RAW Socket으로 저수준에서 프로토콜을 직접 다룰 때 사용


socket 함수 반환 값

성공적으로 소켓을 만들면 0보다 큰 int 값을 반환

소켓지정번호, socket descriptor(소켓 서술자, 소켓의 정보를 담고 있다.)라고 부른다.

소켓을 지시하며, 이를 이용해서 소켓을 제어한다.

일반적으로 소켓을 생성하지 못하면 0보다 작은 값을 반환한다.


IP주소 : IP -> 아파트 위치

Port번호 : TCP -> 호실        = TCP/IP

통신하려면 포트번호와 보관용 메모리 필요 이를 구조체로 선언




INET : TCP/IP 를 이용한 인터넷 주소 패밀리

데이타 연결지향의 신뢰성이 높은 Stream(흔히 TCP 라고 하는)

서버-클라이언트 환경을 만들기 위한 과정을 서버측에서 보자면 다음의 과정을 거치게 된다.

    Socket 생성 -> Socket 에 이름연결 (bind)
    -> 클라이언트의 연결을 기다림(listen)
    -> 클라이언트를 받아들임 (Accept)
    -> 클라이언트의 명령을 받아서 적절한 서비스를 수행

클라이언트측에서 서버에 접근하기 위해서는 단순히 소켓을 생성후 서버에 연결(connect) 하기만 하면 된다.

    Socket 생성 -> 서버에 연결 시도(connect) -> 서버에 각종 명령을 전달가장 먼저 소켓을 생성해야 하는데 이는 socket(2) 함수를 이용하게 된다. 여기에는 3개의 매개 변수가 전달되는데, 각각 통신 도메인의 종류, 통신타입, 사용할 프로토콜을 지원하게 된다. 일반적인 인터넷 어플리케이션의경우 도메인종류로 AF_INET, 그리고 연결지향의 신뢰성 있는 통신을 위해서 SOCK_STREAM 타입을 사용한다.프로토콜은 특별히 지정된게 없으며, 그냥 0을 사용하도록 한다. socket 를 만들었으면 통신 환경에 맞게, sockaddr_in 구조체를 체워주게 된다. 이 구조체의 내용은 다음과 같다.
struct in_addr  
{           
    short int           sin_family;
    unsigned short int  sin_port;
    struct in_addr      sin_addr;
}           
sin_family 는 소켓타입이며, sin_port 는 연결에 사용되는 port(:12) 번호이고, sin_addr 은 연결을 받아들일 IP 어드레스이다. 예제에서는 INADDR_ANY 를 사용했는데, 이는 모든 IP에 대해서 연결을 받아들이라는 뜻이다.

socket() 이용해서 만든 소켓에 이름을 할당하여 실지로 어플리케이션이 사용가능한 상태로 만들어 줘야 하는데 이를 "소켓에 이름을 할당한다" 라고 하며 bind(2) 함수를 이용해서 구현한다. <br> 그다음에 listen(2)를 이용해서 연결을 기다리고, accetp(2) 를 이용해서 연결을 받게 된다. accept 를 이용해서 연결이 완성되면 accept(2) 는소켓과 연결되는 "파일 지시자"를 돌려주고 이 "파일 지시자" 를 통해서 클라이언트와 서버간의 메시지를 주고 받게 된다.

일단 연결이 이루어진다음에 서버가 하는일은 간단하다. 클라이언트의 문자열을 읽어들이고(지역이름), 파일에서 이 지역을 포함한 주소가 있는지 확인해서, 이를 클라이언트측에 전송해주면 된다. 주소검색이 모두 끝났다면 "end" 문자열을 클라이언트에 돌려줌으로써, 모든 검색이 끝났음을 클라이언트에게 알려준다.







connect 함수 메뉴얼



connect 함수의 사용 예

struct socketaddr_in_serveraddr


server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

serveraddr.sin_family = AF_INET;

serveraddr.sin_addr.s_addr = inet_addr("218.234.19.87");

serveraddr.sin_port = htons(8080);

//htons -> (host to network) int    (s) short

//ntohs -> (network to host) int    (s) short

client_len = sizeof(serveraddr);

connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len);


Internet TCP/IP 통신

218.234.19.87 주소로 연결 요청

8080 포트에 연결된 프로그램을 요청

메모리의 크기도 알고있어야 한다.


연결 해보기!!!!


htons에 대한 메뉴얼

여러 가지가 나와 있는데 우리는 지금 htons를 쓰기 때문에 

//htons -> (host to network) int    (s) short

//ntohs -> (network to host) int    (s) short

자세한 설명은 나중에 하도록 하겠다.


inet_addr에 대한 메뉴얼

원래 stAddr.sin_addr.s_addr의 주소를 넣을 때 192.168.10.19 주소를 넣는다면 문자를 16진수로 바꿔서 넣기 때문에 


socket에 대한 메뉴얼



      1 #include <stdio.h>

      2 #include <sys/types.h>

      3 #include <sys/socket.h>

      4 #include <arpa/inet.h>

      5 #include <linux/types.h>

      6 #include <netinet/in.h>

      7 int main()

      8 {

      9         struct sockaddr_in stAddr;

     10         int iSoc;

     11         int iRet;

     12         iSoc = socket(AF_INET, SOCK_STREAM, 0);

     13         if(-1==iSoc)

     14         {

     15             printf("소켓을 생성할 수 없습니다.\n");

     16             return 0;

     17         }

     18         stAddr.sin_family = AF_INET;

     19 //소켓의 첫 번째 인자를 넣는다.

     20         stAddr.sin_port = htons(4000);

     21         stAddr.sin_addr.s_addr = inet_addr("192.168.10.19");

     22         iRet=connect(AF_INET,(struct sockaddr *)&stAddr,sizeof(stAddr));

     23         if(iRet!=0)

     24         {
     25             printf("연결에 실패하였습니다.\n");
     26             close(iSoc);
     27             return 0;
     28         }
     29         printf("iSoc : %d\n iRet : %d \n",iSoc, iRet);
     30         close(iSoc);
     31         return 0;
     32 }      

네트워크 서버에 접속이 되었음!!!!!!!(클라이언트 성공!!!!)