본문 바로가기
Basic/TCP/IP socket

[TCP/IP 프로그래밍] 제1강 : TCP/IP 프로그래밍이란?

by boxbop 2013. 9. 25.
반응형




 보통 TCP/IP 프로그래밍을 소켓 프로그래밍이라고도 부릅니다.

C언어 기반의 통신이 가능한 프로그램을 제작하는거구요~ 저도 공부하면서 포스팅하는거라 미흡한 부분이
많이 있을거같네요ㅠㅠ 상호간의 통신을 가능하게 하려면 필수코스기 때문에 천천히 진행해보도록 하겠습니다.

["네트워크 프로그래밍 = TCP/IP 소켓 프로그래밍"의 개요]

 1. 소켓을 생성합니다.(socket 함수)
 2. IP address와 Port number를 할당합니다. (bind 함수)
 3. 클라이언트 프로그램의 연결 요청을 받아들일 수 있는 상태로 만들어줍니다.(listen 함수)
 4. 클라이언트 프로그램의 연결 요청을 수락합니다. (accept 함수)

1번부터 4번까지 순서대로 진행이 됩니다. 소켓 프로그래밍의 가장 기초가 되는 부분입니다. 이번 장에서는 이 순서만 기억하셔도 반은 다한거라고 볼 수 있겠네요!! 각각의 함수들에 대해서 잠깐 살펴보고 가겠습니다.

*winsock2.h 헤더파일을 include 시켜야 합니다.
*ws2_32.lib 라이브러리를 링크하여 연결해줘야 합니다.

 1. SOCKET socket (int af, int type, int protocol);->성공 시 소켓핸들, 실패 시 INVALID_SOCKET 반환
 2. int bind ( SOCKET s, const struct sockaddr * name, int namelen);-> 성공시 소켓핸들, 실패 시 SOCKET_ERROR 반환
 3. int listen (SOCKET s, int backlog);-> 성공 시 0, 실패 시 SOCKET_ERROR 반환 
 4. SOCKET accept (SOCKET s, struct sockaddr * addr, int * addrlen);->성공 시 소켓핸들, 실패 시 INVALID_SOCKET 반환

위의 내용은 서버측에서 수행해야 될 부분입니다. 즉 accept 함수가 돌고 있을때 클라이언트 프로그램에서는 뭔가 연결을 시도하고 어떠한 행동을 하겠죠? 서버에 비해 클라이언트는 아주 간단합니다. 소켓을 생성하고 연결해주기만 하면 되는거죠. 그 과정은 다음과 같습니다.

 1. SOCKET socket (int af, int type, int protocol);->성공 시 소켓핸들, 실패 시 INVALID_SOCKET 반환
 2. int connect (SOCKET s, const struct sockaddr * name, int namelen);->성공 시 0,  실패 시 SOCKET_ERROR 반환

자 마지막으로 서버와 클라이언트에서는 소켓을 사용하고 닫아주는 과정이 필요합니다. 사실 리눅스의 경우 소켓도 파일로 간주하기 때문에 close함수를 사용하지만 윈도우에서는 다르기 때문에 아래와 같은 함수를 사용해서 소켓을 닫아줍니다.

 int closesocket (SOCKET s);->성공 시 0, 실패시 SOCKET_ERROR 반환

네 딱 여기까지가 서버와 클라이언트 프로그램에서의 기초입니다. 하지만 중요한 한가지가 빠졌네요 ㅠ 윈도우에서 소켓 프로그래밍을 할때는 WSAStartup 함수를 제일 먼저 호출해줘야 합니다. 이 함수는 소켓 버전과 해당 버전을 지원하는 라이브러리의 초기화를 해줍니다. 그냥 공식처럼 사용하셔야 됩니다.

 int WSAStartup (WORD wVersionRequested, LPWSADATA lpWSAData);->성공 시 0, 실패 시 0 이 아닌 에러 코드 반환
-> WORD는 unsigned short 형을 재정의 한겁니다. wVersionRequested 라는 인자는 소켓의 버전을 말하는대요. 여기에는 MAKEWORD()라는 함수를 사용하여 인자를 전달합니다. 예를 들어 소켓의 버전이 2.2 버전이라면 MAKEWORD(2,2) 를 wVersionRequested 값에 넣어줍니다. 쉽죠? lpWSAData인자의 경우는 WSADATA 구조체 변수의 주소값을 전달합니다. WSAStartup 함수가 호출되고 난 다음에는 lpWSAData 인자에 초기화된 라이브러리의 정보가 저장된다고 합니다. 두 번째 인자는 그냥 가볍게 넘어갑시다~ WSADATA 형의 변수인 wsadata를 선언하고 &wsadata 그대로 전달해주면 되니까요~
(ex>WSAStartup(MAKEWORD(2,2), &wsadata) )

 int WSACleanup (void);->성공 시 0, 실패 시 SOCKET_ERROR 반환
->그리고 프로그램의 마지막 부분에서 lpWSAData 인자에 들어있는 라이브러리의 정보를 해제하기 위해 WSACleanup 함수를 호출해줍니다.

 여기서 또 한가지 살펴보고 넘어가야할 부분이 있습니다. 바로 "핸들"이죠. 리눅스에서는 이것을 파일디스크립터라고 부릅니다. 파일디스크립터 또는 핸들은 운영체제가 파일 또는 소켓을 지칭하기위해 부여된 숫자입니다. 리눅스에서는 소켓도 파일로 취급하기때문에 파일 디스크립터로 지칭하지만 윈도우는 파일 핸들과 소켓 핸들을 구분하고 있습니다. 의미는 같지만 서로 다른 함수를 사용하여 취급하기 때문에 구분한다고 보시면 될 듯 싶습니다.

*윈도우 소켓 프로그래밍의 소켓 기반 데이터 입출력 함수(윈도우는 파일과 소켓이 다르기 때문에 구분해서 함수를 사용)
1. int send (SOCKET s, const char * buf, int len, int flags);->성공 시 전송된 바이트 수, 실패 시 SOCKET_ERROR 반환
2. int recv (SOCKET s, const char * buf, int len, int flags);->성공 시 수신된 바이트 수, 실패 시 SOCKET_ERROR 반환

 이번 강은 여기서 마치도록 하겠습니다~! 최대한 나중에 복습할 때도 이해하기 쉽도록 설명을 하긴하는대 어떨지 모르겠네요.


 


반응형