윈도우 소켓 프로그래밍(TCP)

카테고리 없음 2014. 2. 5. 07:35

소켓을 생성할때는 라이브러리에서 제공하는 소켓생성 구조체를 사용합니다. SOCKET 구조체는 주소,

소켓타입 프로토콜 등을 사용자가 직접 지정해 주어야 합니다.

 

생성후 사용자가 요청한 프로토콜을 이용하여 통신할수 있도록 내부적으로 리소스를 할당해, 접근시 핸들값

(SOCKET 타입, 32비트 정수)의 디스크립터를 리턴합니다. 프로토콜시 자주 이용하는 것은 TCP, UDP입니다.(AF_INET)

 

소켓통신이 끝나면 리소스를 반환해야 합니다. 쉽게 말하면 메모리를 할당한뒤 free하는것가 같습니다.

소켓 리소스 제거는 closesocket() 를 사용해 소켓 리소스를 제거합니다.


TCP서버, 클라이언트는 다음과 같은 순서로 소켓 함수를 호출합니다.

클라이언트는 서버와 달리 bind()함수를 호출하지 않습니다. Bind()함수 없이 connect()함수를 호출하면

OS는 자동적으로 지역 IP주소와 포트번호를 설정합니다.

 

- Socket : 소켓생성

- Connect() : 서버에 접속 요청

- Send(), recv() : 데이터 전송, 수신 함수로 서버/클라이언트 와 통신을 수행합니다.

- Closesocket() : 소켓을 종료합니다.

 

Connect()함수는 서버에게 접속하여 TCP 프로토콜 수준의 연결을 설정합니다.

s: 서버와 통신하기 위해 만든 소켓, name : 서버 주소를 초기화 한 소켓 구조체 변수의 주소값

 namelen : 소켓 구조체 변수의 길이



SOCKADDR_IN serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("128, 0, 0, 1");
int retval = connect(sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
if(retval == SOCKET_ERROR)
err_quit("connect()");

데이터 전송은 Send()함수를 이용합니다.

데이터를 송신 버퍼에 복사함으로 프로토콜에 의해 데이터가 전송 되도록 합니다.

 s : 통신할 대상과 연결된 소켓, buf : 보낼 데이터를 담고 있는 어플리케이션 버퍼의 주소

 len : 보낼 데이터 크기, Flags : send() 함수의 동작을 바꾸는 옵션(대부분 0을 사용)

 

데이터 수신 함수는 recv()함수를 사용합니다.

수신 버퍼에 도착한 데이터를 어플리케이션의 버퍼로 복사합니다.

s : 통신할 대상과 연결된 소켓, buf : 받은 데이터를 저장할 어플리케이션 버퍼의 주소, len : 수신 버퍼로 부터 복사할 최대 크기

 flags : recv()함수의 동작을 바꾸는 옵션(대부분 0을 사용)

recv()함수 사용시 주의점은 TCP메시지 경계를 구분하지 않기 때문에, 세번째 인자인 len으로 지정한 크기보다

작은 데이터가 어플리케이션 버퍼로 복사될수 있습니다. 따라서 자신이 받을 데이터의 크기를 알고 있다면,

해당 크기만큼 받을때 recv() 함수를 여러번 호출해야 합니다.

 

어플리케이션 프로토콜과의 메세지 설계를 할때 경계 구분 세가지 방법을 소개합니다.

송신자 입장에서는

1. 항상 고정길이 데이터를 보냄

2. 경계 구분을 위해 특별한 표시(eor : End of Record)

3. 보낼 데이터 길이를 고정 길이 데이터로 보낸후, 가변 길이 데이터를 이어서 송신(헤더 추가)

 

수신자 입장에서는

1. 항상 고정 길이 데이터를 수신

2. EOR이 나올때 까지 데이터를 읽은 후 처리

3. 고정 길이 데이터를 읽어 뒤 따라올 데이터의 길이를 알아냄, 이 길이만큼 데이터를 읽어 처리(헤더를 읽고 처리)

가장 많이 사용되는 방법은 3번 입니다.

 

 

소켓 프로그래밍

카테고리 없음 2014. 2. 5. 07:12

소켓은 네트워크를 통한 입/출력을 하기 위해 사용자에게 필요수단을 제공하는 응용 프로토콜 인터페이스를 말합니다.

네트워크 입출력을 하기 위해서는 프로토콜, 소스 IP주소, 소스 포트 번호, 목적지 IP주소, 목적지 포트번호 총 5가지의

요소가 필요합니다.

 

C/C++에서 파일 입출력을 통해 파일을 open, read, write하는것과 동일한 방식으로 socket을 생성해 recv(받기),

send(보내기)등의 작업을 할수 있습니다.

 

소켓은 네트워크 인터페이스 층면에서 어플리케이션 층과 TCP/UDP층 사이에 소켓 인터페이스 계층이 존재하여

두 계층을 서로 연결해주는 다리 역활을 합니다.

윈도우 상에서의 소켓 프로그래밍은 윈도우에서 지원하는 Winsock을 사용하여 소켓프로그래밍을 작성합니다.

상당부분 BSD계열 유닉스 소켓을 참고로 설계되었기 때문에 많은 부분이 리눅스 기반 소켓과 유사합니다.

윈도우 소켓을 사용하려면

1. Winsock2.h 헤더파일을 포함합니다.

2. Ws2_32.lib 라이브러리를 링크합니다.

3. 윈도우 소켓 사용을 위한 라이브러리를 참조해 소켓생성, 전송, 수신 등을 사용해 소켓 통신을 합니다.

 

 

Ws2_32.lib 라이브러리를 링크할시,

와 같이 파일에 직접 추가하거나

프로젝트 속성 -> 구성 속성 -> 링커 -> 입력 -> 추가종속성 란에 아래 그림과 같이 입력해 주면 됩니다.

 

 

네트워크 프로그래밍에서는 여러 원인으로 인해 오류가 발생하고, 오류 발생 확률이 높기 때문에 오류처리코드를

작성해 각 오류에 대해 대응(예외)하는 부분이 필요합니다. 각각의 함수 리턴값을 이용하여 오류 목록을 확인하고

그에 대해 적절히 처리될수 있도록 작성되어야 합니다. 예)WSAStartup()

사용 예는 아래 사진과 같습니다.