물마중
Windows에서 소켓프로그래밍하기-기초 본문
으흠~~ 소켓프로그래밍을 할 때 꼭 들어가야 하는 필수 함수들을 정리해보고 가자~~!!
(이렇게 정리를 하고 가면 나중에 까먹어도 쉽게 찾을 수 있으니깐~~)
Let's~~~~~~~~~~~~~~~ GO~!!!
==========================================================================================
소켓 통신을 할 때 윈도우즈에서 가장 먼저 시행되어야 할 함수는 WSAStartup()함수이다.
머하는 함수인고 하니...
사용할 윈도우소켓의 버전을 명시하고, 소켓 관련 정보들을 리턴하는 함수.
이 함수를 실행시키지 않으면 다른 소켓관련 함수들을 쓸 수 없다고 한다. 인자 값으로는 2개의 인자가 들어간다. 인자의 용도와 인자의 쓰임을 정리해보자.
원형 : WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);인자 : WORD wVersionRequested =-> 사용할 윈도우 소켓의 버전을 명시
LPWSADATA lpWSAData =-> 소켓 정보를 저장할 공간
간단한 팁을 써보면 소켓의 버전을 명시할 때 상위는 마이너 버전이고, 하위는 메이저 버전을 뜻하기 때문에 MAKEWORD()를 이용하면 쉽게 버전을 만들수 있다. 함수 사용은 아래 있는 예제를 참고하자.!!
그리고 마지막에는 꼭 치워줘야 하겠지.. 이 때 사용하는 함수가 WSACleanup()이다. 인자는 없고 WSAStartup()이 나오면 반드시 마지막에 WSACleanup()으로 마무리 짓자.
이제부터 진짜 소켓을 생성하고 데이터를 주고받는 함수들이다.~
소켓을 생성할 차례이다. 소켓을 생성할 때 사용하는 함수는 socket()이다. 원형을 살펴보자.
원형 : SOCKET WSAAPI socket(
__in int af,
__in int type,
__in int protocol
)
3개의 인자를 사용하는데 각 인자에 대해서 정리하여보자.
1. __in int af
MSDN에서는 The address family specification이라고 정의내리고 있는데 주소 가족?? 무슨 말인지 모르겠지만 인자로 쓰이는 아래 네모 표를 보면 대충 이해할 수 있을 것이다.
AF_UNSPEC | The address family is unspecified |
AF_INET | The IPv4 address family |
AF_NETBIOS | The NetBIOS address family |
AF_INET6 | The IPv6 address family |
표의 설명은 MSDN에 있는 설명을 짤막하게 가져왔다. 더 많은 내용이 있지만 그 부분은 MSDN(너무~ 좋아 *^^*)을 참고하기 바란다.
표의 내용을 보면 감이 오지 않는가?? 첫 번째 변수는 어떤 형태의 네트워크인가를 나타내고 있다. 현재는 대부분 IPv4를 사용하기 때문에 AF_INET으로 설정하면 될 것이다. 이제 곧 AF_INET6를 쓸 날이 오겠지만~~~.. = )
2. __in int type
만들어질 소켓의 유형을 정의하는 인자이다. 어떤 타입이 있는지 살펴보자.
SOCK_STREAM | TCP |
SOCK_DGRAM | UDP |
SOCK_RAW | raw socket that allows an application to manipulate the next upper-layer protocol header. |
SOCK_RDM | a reliable message datagram. |
SOCK_SEQPACKET | pseudo-stream packet based on datagrams. |
음.. 역시 영어는 어렵다. 가장 많이 쓰이는 타입은 당연히 SOCK_STREAM과 SOCK_DGRAM이다. 나중에 이 쪽에 관련된 일을 하게 된다면 다른 형태의 타입도 사용해보겠지만 현재는 TCP와 UDP에서 사용되는 2가지만 알아도 무사통과이지 싶다. 고로 더 자세한 내용은 패쓰..(여기는 기초부분이므로 =- )
3. __in int protocol
헛.. 이 넘은 머하는 놈일까? 우선 0으로 셋팅하면 기본적인 소켓프로그래밍에서는 지장이 없어 보인다. MSDN에서는 이 넘을 0으로 설정하면 특별한 프로토콜을 규정하기를 원하지 않는다고 한다. 그리고 서비스가 사용하기 위한 프로토콜을 선택할 것이라고 되어있다.(오역이면 지적 좀.. ) 타입이 4종류가 나와있지만 기초부분에서 다룰 필요가 없어 보이니 넘어가도록 하자.
socket()은 정상적으로 수행하였다면 소켓 디스크립터를 반환한다. 이 디스크립터는 데이터를 전송하거나 받을 때 사용하는 send()와 recv()에서 사용된다. socket()으로 소켓을 생성하였다면 소스 마지막 부분에 closesocket(SOCKET s)를 이용하여 소켓을 닫아줘야 한다. !_!
자.. 소켓을 만들었으면 만들어진 소켓과 타켓을 연결해야 겠다. 이 행위를 위해 존재하는 함수가 connect()이다. 그럼 함수가 나왔으니 또 원형을 살펴볼까~~ (힘들구나.. 헥헥..)
원형 : int connect(
__in SOCKET s,
__in const struct sockaddr *name,
__in int namelen
);
3개의 인자를 넘겨받아서 수행되는 함수이다. 각 인자를 살펴볼까~ (후비고~~!)
1. __in SOCKET s
다들 쉽게 눈치 챘을 거 같다. ㅋㅋ 바로 위에서 알아본 socket() 함수의 리턴 값이다.2. __in const struct sockaddr *name
타켓의 주소를 지정하는 곳으로 sockaddr 구조체의 포인터를 입력하면 된다. inet_addr()을 이용하면 문자열로 된 IP주소를 sockaddr구조체로 바꿀 수 있다.3. __in int namelen
sockaddr 구조체의 크기를 지정해주면 된다.리턴값 : 정상적인 수행을 완료했으면 0을 리턴한다.
connect()에 대해서도 알아보았다. connect()는 socket()에 비하여 비교적 알아볼 내용이 적었다. connect()가 정상적으로 수행되었다면 타켓 호스트와 데이터를 주고 받을 수 있다.
이제 실질적으로 데이터를 주고 받는 기초적인 함수인 recv()와 send()를 살펴보자.
우선 recv()부터닷~!
원형 : int recv(
__in SOCKET s,
__out char *buf,
__int int len,
__in int flags
);
4개나 되는 인자를 사용하는 구나... 위의 함수들 처럼 자세히 하지 않고 간단하게 집고 넘어가자.
첫 번쨰 변수야 다들알 것이니 패쓰(모르겠다면 다시 위로~), 두 번쨰 변수는 받은 데이터를 저장할 장소이고 세 번째 변수는 받을 데이터의 크기이다. 4번째 인수는 왜 사용하는지 잘 모르겠다. 저 값이 설정되는 예제를 본적도 없고 말이다. __;; 리턴 값은 실제 읽어들인 바이트의 개수이다.
정말 간단히 알아보았다(너무 길어져서 ㅠ_ㅠ). 다음은 send를 알아보자.!
원형 : int send(
__in SOCKET s,
__in const char *buf,
__in int len,
__in int flags
)
이 함수는 recv와 반대의 역할을 수행한다. 첫 번째 인자는 동일하고 두 번째와 세 번째 인자는 recv와 반대로 전송하기 위한 데이터의 위치와 데이터의 크기이다.
==========================================================================================
아흠 긴 여정이였다.. 이번 정리에서 아쉬운 점은 함수들의 인자로 쓰이는 다양한 인자들의 쓰임세와 에러들을 모두 정의해보지 못한 것이다. 윈도우즈 소켓프로그래밍은 소켓에 관련된 함수가 에러를 내면 WSAGetLastError()을 이용하여 확인할 수 있다.
마지막으로 vortex0번 문제 풀 때 사용한 예제를 올리고 맞추겠다.
#include <stdio.h> int main(void) WSAStartup(MAKEWORD(2, 2), &wsadata); sock_p = socket(PF_INET, SOCK_STREAM, 0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; for (i = 0; i < 4; i++) { send(sock_p, (char *)&sum, sizeof(unsigned int), 0); printf(result); closesocket(sock_p); return 0; |
'Programming > Windows System' 카테고리의 다른 글
[Windows System] 파일 입출력(File Input/Output) (0) | 2011.02.25 |
---|---|
[Windows System] 가상 메모리(Virtual Memory) (0) | 2011.02.24 |
[Windows System] 쓰레드(Thread) 동기화에 대한 개념정리 (0) | 2011.02.10 |
[Windows System] 쓰레드(Thread) 동기화 - 순차 실행 관점 (0) | 2011.02.10 |
[Windows System] 쓰레드(Thread) 동기화 - 메모리 접근 관점 (0) | 2011.02.10 |