SYSTEM PROGRAMMING

TCP/IP 소켓 프로그래밍 01. 네트워크 프로그래밍과 소켓의 이해

뉴암스테르담 2015. 8. 5. 21:22
TCP/IP 소켓 프로그래밍 01. 네트워크 프로그래밍과 소켓의 이해  시스템프로그래밍 

2013.03.15. 21:22  수정  삭제

복사http://blog.naver.com/pwk0810/40183953612

전용뷰어 보기

1단계. 소켓 생성( socket)

2단계. IP 주소와 PORT 번호 할당 ( bind 함수 호출 )

3단계. 연결 주소와 가능 상태로 변경 ( listen 함수 호출)

4단계. 연결 요청에 대한 수락 (accept 함수 호출 )

 

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

 

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

 

int listen(int sockfd, int baklog);

 

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

 

 

전화 버는 소켓의 구현

 

#include <sys/socket.h>

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

 

01-2. 리눅스 기반 파일 조작하기.

 

 

  • 리눅스에서는 소켓 조작은 파일 조작과 동일하게 간주됨.
  • 때문에 소켓을 파일의 일종으로 구분.
  • 파일 입출력 함수를 소켓 입출력에, 네트워크 상에서의 데이터 송수신에 사용할수 있다.
  • 윈도우는 리눅스와 달리 파일과 소켓을 구분함.

저수준 파일 입출력( Low-level file access )과 파일 디스크립터 ( file descriptor)
  • 표준에 상관없이 운영체제가 독립적으로 제공.
  • 리눅스에서 제공하는 함수 / ANSI 표준에서 제공하는 함수가 아니라는 뜻.
  • 파일 디스트립터는 시스템으로 부터 할당 받은 파일 또는 소켓에 부여된 정수라는 의미 (윈도우에서의 핸들?)  
  • 파일 디스크립터란 운영체제가 만든 파일 또는 소켓의 지칭을 편히 하기 위해서 부여된 숫자에 지니지 않는다.
  • 때문에 파일 디스크립터를 파일 핸들이라고 한다.
파일 열기
  • int open(const char* path , int flag );
    • flag : 파일의 오픈 모드 전달. ( O_CREATE : 필요하면 파일을 생성 , O_APPEND : 기존 데이터 보존하고, 뒤에 이어서 저장 , O_RDWR : 읽기 , 쓰기 겸용으로 파일 오픈 )

파일 닫기

 

  • int close(int fd);
    • fd  :닫고자 하는 파일 또는 소켓의 파일 디스크립터 전달.

 

파일에 데이터 쓰기

 

  • ssize_t write(int fd, const void* buf, size_t nbytes);
    • fd : 파일 디스크립터
    • buf : 전송할 데이터가 저장된 버퍼의 주소값 전달.
    • nbytes : 전송할 데이터의 바이트 수 전달.
  • if(write(fd, buf, sizeof(buf)) == -!)
    • char buf[] = "Hello World!\n" ;

 파일에 데이터 쓰기

 

  • ssize_t read(int fd, void* buf , size_t nbytes);
    • buf :  수신한 데이터를 저장할 버퍼의 주소 값 전달
  • if(read(fd, buf, sizeof(buf)) == -1)
    • buf : char buf[100];

 

파일 디스크립터와 소켓

 

  • int fd1 = socket(PF_INET , SOCK_STREAM , 0 );
  • int fd2 = open("test.dat" , O_CREATE | O_WONLY | O_TRUNC );
  • int fd3 = socket(PF_INET , SOCK_DRAM , 0);

 

01-3. 윈도우 기반으로 구현하기

 

  • 윈속은 BSD 계열 유닉스 소켓을 참고하여 설계.
+ 윈도우 소켓을 위한 헤더와 라이브러리의 설정
  • 헤더파일 winsock2.h 를 포함
  • ws2_lib.lib 라이브러리에 링크 ( 프로젝트 속성 - 링커 - 입력 - 추가 종속성 )
+ 윈속 초기화
  • int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData);
  • WSADATA wsaData;
  • if(WSAStartup(MAKEWORD(2,2) , &wsaData ) != 0) 주버전 2, 부버전 0x0202 반환.

  • WSAStartup 으로 프로그램에서 요구하는 윈도우 소켓버전을 알림
  • int WSACleanup(void );
01-4. 윈도우 기반의 소켓 관련 함수와 예제.

+ 윈도우 기반 소켓 관련 함수들
  • SOCKET socket(int af, int type, int protocol);
  • int bind(SOCKET s, const struct sockaddr *name,  int namelen) ;
  • int listen(SOCKET s, int backlog);
  • SOCKET accpet(SOCKET s, struct sockaddr* addr, int *addrlen );
  • int connect(SOCKET s, const struct sockaddr* name, int namelen);
  • int closesocket(socket s);
+ 윈도우 에서의 파일 핸들과 소켓 핸들
  • 리눅스와 마찬가지로 윈도우에서도 함수의 호출을 통해서 팡리을 생성할때 핸들(handle)이라는 것을 반환
  • 리눅스의 파일 디스크립터에 비교될수 있음
  • 그러나 윈도우는 소켓핸들과 파일 핸들을 구분함. (  socket s / handle s )
  • 핸들이라는 관점에서 보기는 동일하나 리눅스처럼 완벽하게 동일하지는 않음.
  • 윈도우와 리눅스 운영체제의 커널은 구조적으로 차이가 있으며, 운영체제에 따른 코드의 구현 스타일도 각각 별도로 존재한다. 
+ 윈도우 기반 입출력함수

  • int send(SOCKET s , const char *buf , int len , int flags);
    • flags : data 전송시 적용할 다양한 옵션 정보 전달.

  • int recv(SOCKET s,  cont char * buf , int len, int flag) ;