int   server_socket;
   int   client_socket;
   int   client_addr_size;

   struct sockaddr_in   server_addr;
   struct sockaddr_in   client_addr;

   char   buff_rcv[BUFF_SIZE+5];
   char   buff_snd[BUFF_SIZE+5];




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

domain 

  • PF_INET, AF_INET : IPv4인터넷 프로토콜을 사용
  • PF_INET6 : IPv6인터넷 프로토콜을 사용
  • PF_LOCAL, AF_UNIX : 같으 시스템 내에서 프로세스끼리 통신합니다.
  • PF_PACKET : Low level socket 을 인터페이스를 이용
  • PF_IPX : IPX 노벨 프로토콜을 사용
type
  • SOCK_STREAM : TCP/IP 프로토콜을 이용 
  • SOCK_DGRAM : UDP/IP 프로토콜을 이용
protocol : 통신에 있어 특정 프로토콜을 사용을 지정하기 위한 변수 ,보통 0값을 사용

성공 시 파일 디스크립터, 실패 시 -1 반환

 server_socket  = socket( PF_INET, SOCK_STREAM, 0);
   if( -1 == server_socket)
   {
      printf( "server socket 생성 실패\n");
      exit( 1);
   }

 



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

  • sockfd : 소켓 디스크립터
  • sockaddr *myaddr : 주소 정보로 인터넷을 이용하는 AF_INET인지 시스템 내에서                              통신하는  AF_UNIX에 따라서 달라집니다. 

                                 인터넷을 통해 통신하는 AF_INET인 경우에는 struct sockaddr_in을                                  사용합니다.

  • socklen_t addrlen : myadd 구조체의 크기 ex) size(sock_addr)

성공 시 0 , 실패 시 -1 반환

 if( -1 == bind( server_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
   {
      printf( "bind() 실행 에러\n");
      exit( 1);
   }

주소정보의 표현 (sockaddr/ sockaddr_in)

  • sockaddr : 소켓주소를 표현하는 구조체 
TCP/IP만을 목적으로 만들어진 것이 아니기 때문에, 다양한 주소체계에 맞게 범용 목적으로 사용하기 위해이런 단순한 구조를 가지고있다.

struct sockaddr{
sa_family_t sa_family ; 소켓 주소체계
char          sa_data[4]; 해당 주소체계에서 사용하는 주소정보

  • sockaddr_in : IPv4 주소체계에서 사용하는 구조체
소켓 프로그램은 범용 주소 구조체로 sockaddr을 사용하지만, 주소체계의 종류에 따라 별도의 전용 구조체를 만들어 사용하는게 편리하다.

struct sockaddr_in {
sin_family_t         sin_family; IPv4주소 체계에서 사용하므로 항상 AF_INET으로 설정
unist16_t             sin_port; 포트번호
struct     in_addr  sin_addr; IP주소를 나타내는 32비트 정수 타입구조체
char                   sin_zero[8]; sockaddr과 같은 크기를 유지하기 위해 필요한                                                     패딩공간. 항상 0

struct in_addr {
unit32_t              s_addr; 32비트 IPv4 인터넷 주소
}


sin_family : 주소체계(AF_INET / AF_INET6 / AF_LOCAL)

sin_port : 16비트 포트정보

sin_addr : 32비트 IP정보

sin_zero : 사용되지 않는 필드








3. int listen(int sockfd, int backlog);

  • sockfd : 소켓 디스크립터
  • backlog : 대기 메시지 큐의 개수

성공시 0, 실패 시 -1 반환

  if( -1 == listen(server_socket, 5))
   {
      printf( "listen() 실행 실패\n");
      exit( 1);
   }


 

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

  • sockfd : 소켓 디스크립터
  • sockaddr *addr : 클라이언트 주소정보를 가지고 있는 포인터
  • socklen_t addrlen : struct sockaddr *addr 포인터가 가르키는 구조체의 크기

성공 시 파일 디스크립터, 실패 시 -1 반환

while( 1) { client_addr_size = sizeof( client_addr); client_socket = accept( server_socket, (struct sockaddr*)&client_addr, &client_addr_size); if ( -1 == client_socket) { printf( "클라이언트 연결 수락 실패\n"); exit( 1); }

 



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

  • sockfd : 소켓 디스크립터
  • sockaddr *serv_addr : 서버 주소 정보에 대한 포인터
  • socklen_t addrlen : struct sockaddr *serv_addr 포인터 가르키는 구조체의 크기

성공시 0, 실패 시 -1 반환

  if( -1 == connect( client_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
   {
      printf( "접속 실패\n");
      exit( 1);
   }

 

 


TCP/IP 통신 함수 사용순서




서버프로그램 예제

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( void)
{
   int   server_socket;
   int   client_socket;
   int   client_addr_size;

   struct sockaddr_in   server_addr;
   struct sockaddr_in   client_addr;

   char   buff_rcv[BUFF_SIZE+5];
   char   buff_snd[BUFF_SIZE+5];



   server_socket  = socket( PF_INET, SOCK_STREAM, 0);
   if( -1 == server_socket)
   {
      printf( "server socket 생성 실패\n");
      exit( 1);
   }

   memset( &server_addr, 0, sizeof( server_addr));
   server_addr.sin_family     = AF_INET;
   server_addr.sin_port       = htons( 4000);
   server_addr.sin_addr.s_addr= htonl( INADDR_ANY);

   if( -1 == bind( server_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
   {
      printf( "bind() 실행 에러\n");
      exit( 1);
   }

   if( -1 == listen(server_socket, 5))
   {
      printf( "listen() 실행 실패\n");
      exit( 1);
   }

   while( 1)
   {
      client_addr_size  = sizeof( client_addr);
      client_socket     = accept( server_socket, (struct sockaddr*)&client_addr, &client_addr_size);

      if ( -1 == client_socket)
      {
         printf( "클라이언트 연결 수락 실패\n");
         exit( 1);
      }

      read ( client_socket, buff_rcv, BUFF_SIZE);
      printf( "receive: %s\n", buff_rcv);
      
      sprintf( buff_snd, "%d : %s", strlen( buff_rcv), buff_rcv);
      write( client_socket, buff_snd, strlen( buff_snd)+1);          // +1: NULL까지 포함해서 전송
      close( client_socket);
   }
}

 클라이언트 프로그램 예제

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( int argc, char **argv)
{
   int   client_socket;

   struct sockaddr_in   server_addr;

   char   buff[BUFF_SIZE+5];

   client_socket  = socket( PF_INET, SOCK_STREAM, 0);
   if( -1 == client_socket)
   {
      printf( "socket 생성 실패\n");
      exit( 1);
   }

   memset( &server_addr, 0, sizeof( server_addr));
   server_addr.sin_family     = AF_INET;
   server_addr.sin_port       = htons( 4000);
   server_addr.sin_addr.s_addr= inet_addr( "127.0.0.1");

   if( -1 == connect( client_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
   {
      printf( "접속 실패\n");
      exit( 1);
   }
   write( client_socket, argv[1], strlen( argv[1])+1);      // +1: NULL까지 포함해서 전송
   read ( client_socket, buff, BUFF_SIZE);
   printf( "%s\n", buff);
   close( client_socket);
   
   return 0;
}


블로그 이미지

왕왕왕왕

,