본문 바로가기

개인 공부/네트워크

네트워크P-003(윈속 & 소켓)

2023.04.09 - [개인 공부/네트워크] - 네트워크P-002(네트워크 모델 & Socket)

 

네트워크P-002(네트워크 모델 & Socket)

네트워크 연결 모델 인터넷은 프로그램과 프로그램의 연결 클라이언트 & 서버 모델 (Client & Server) 매니저 & 에이전트 모델 (Manager & Agent) P2P 모델 (Peer To Peer) Client & Server Model 서비스를 요청하는 쪽

jisu069.tistory.com

윈속 초기화 및 종료

 

윈속 응용프로그램의 공통 구조

헤더정보

  • 윈속을 사용하려면 먼저 WinSock2 헤더에 포함하고 ws2_32.dll을 링크해야한다
    • #includ <WinSock2.h>
    • 윈속 라이브러리 참조 : #pragma comment(lib, "ws2_32") == 프로젝트 속성에서 ws_32.dll 추가
  • 다양한 함수들과 서브시스템에서 사용되는 데이터타입들과 윈도우API의 함수들을 위한 정의 
    • #include <Windows.h>
  • 윈속 : #include <WinSock2.h>
  • 입출력 정보 : #include <stdio.h>

WSADATA 구조체

  • 윈도우 소켓버전, 최대 사용할 수, 소켓의 수 정보 제공
typedef struct WSAData{
	WORD	wVersion; // 버전
    WORD	wHighVersion;	// 사용할 수 있는 상위 버전으로 wVersion과 일치
    char	szDescription[WSADESCRIPTION_LEN + 1];	// 윈속 설명
    char	szSystemStatus[WSASYS_STATUS_LEN + 1];	// 상태 문자열
    unsigned short	iMaxSockets;	// 최대 소켓
    unsigned short	iMaxUdpDg;		// 데이터 그램의 최대 크기
    char FAR *	lpVendorInfo;		// 벤더 정보(큰 의미 없다고 함!)
}  WSADATA, FAR * LPWSADATA;

// WORD 또는 DWORD : win32 API에서 제공해주는 자료형, CPU가 한번에 처리할 수 있는 데이터의 크키 단위를 의미
// unsigend short 정수형 자료형으로 양수만 사용!!
  • Winsock2 라이브러리에서 제공해주는 함수
  • 윈속 라이브러리(ws2_32.dll)를 초기화 하는 역할
int WSAStartup(
	WORD wVersionRequested,
	LPWSADATA lpWSAData
);

// 성공 : 0 
// 실패 : 오류코드

- wVersionRequested

  • 프로그램이 요구하는 최상위 윈속 버전
  • MAKEWORD(2,2) : 2.2의 버전을 넣는다는 의미!

- lpWSAData

  • WSADATA라는 구조체 변수의 주소값 전달 -> 초기화할 윈속
  • 윈도우 운영체제가 제공하는 윈속 구현에 대한 정보를 얻을 수 있다

윈속 종료

int WSACleanup(void);
// 성공 : 0
// 실패 : SOCKET_ERROR

initWinsock.cpp(윈속 생성과 종료)

int main(){
	// ========== 윈속 초기화 ==========
	WSADATA wsa;
	if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
		return 1;
	printf("[알림] 윈속 초기화 선공\n");

	// ========== 소켓 생성 ==========
	// ========== 통신 ==========
	// ========== 소켓 닫기 ==========

    // ========== 윈속 종료 ==========
    WSACleanup();
    return 0;
}

소켓 생성과 닫기

소켓 생성 & 닫기

소켓 생성

  • 소켓을 사용해 통신하려면 통신 양단이 같은 프로토콜을 사용해야 한다
  • TCP 사용하는지 UDP 사용하는지!
/*	Windows		*/
#include <winsock2.h>

SOCKET socket(
	int af,			// 주소 체계
	int type,		// 소켓 타입
	int protocol	// 프로토콜
)
// 생성 : 새로운 소켓
// 실패 : INVALID_SOCKET
/*	Linux	*/
#include <sys/types.h>
#include <sys/socket.h>

int socket(
	int domain,		// 주소 체계
	int type,		// 소켓 타입
	int protocol	// 프로토콜
);
// 성공 : 새로운 소켓
// 실패 : -1

소켓 생성 구조체

SOCKET socket(
	int af,			// 혹은 Domain -> 주소 체계
	int type,		// 소켓 타입
	int protocol	// 프로토콜
)
  • 사용자가 요청한 프로토콜을 사용해 통신할 수 있도록 내부적으로 리소스를 할당
  • 접근할 수 있는 일종의 핸들 값(SOCKET 타입, 32bit 정수)인 소켓 디스크럽터(socket descriptor)를 리턴

소켓 생성 구조체 - 주소 체계

  • 통신을 하려면 상대를 유일하게 지정할 수 있는 주소가 필요하다
  • 주소 지정 방법 : 네트워크 프로토콜의 종류에 따라 달라짐
  • AF(or도메인) : 주소 여역을 지정하기 위해 사용
AF_UNSPEC 0 정의되지 않은
주소 영역
AF_INET 2 IPv4 주소
영역에서 사용
AF_IPX  6 IPX/SPX 주소
영역에서 사용
AF_APPLETALK 17 AppleTalk 에서 사용
AF_NETBIOS 17 NetBIOS 주소
영역에서 사용
AF_INET6 23 IPv6주소
영역에서 사용
AF_IRDA 26 Infrared Data
Association 주소
영역에서 사용
AF_BTH 3 bluetooth 주소 영역에서 사용

 


소켓 생성 구조체 - 소켓 타입

  • 소켓이 생성될 때 소켓의 타입도 결정되어야 한다
    • 연결 지향형 소켓 타입(TCP)
    • 비 연결 지향형 소켓 타입(UDP)
  • 데이터 전송 방식을 의미
소켓 타입 특성
SOCK_STREAM 신뢰성 있는 데이터 전송 기능 제공
연결형 프로토콜(TCP/IP)기반의
양방향 통신을 위해 사용
SOCK_DGRAM 신뢰성 없는 데이터 전송기능 제공
비연결형 프로토콜(UDP/IP)기반의
통신을 위해 사용
  • 연결 지향형 소켓(SOCK_STREAM)의 데이터 전송 특성
    • 중간에 데이터가 소멸되지 않는다
    • 전송 순서대로 데이터가 수신된다
    • 데이터의 경계가 존재하지 않는다
    • 소캣 대 소켓의 연결은 반드시 1:1 구조!!
  • 비 연결지향형  소켓(SOCK_DGRAM)의 데이터 전송 특성
    • 전송 순서 상관없이 빠른 속도의 전송을 지향
    • 데이터 손실 및 파손의 우려가 있다
    • 데이터의 경계가 존재한다
    • 한번에 전송할 수 있는 데이터의 크기가 제한된다

소켓 생성 구조체 - 프로토콜

  • 주소 체계와 소켓 타입이 같더라도 해당 프로토콜이 두 개 이상 존재할 경우 프로토콜을 명시적으로 지정해야 한다
  • 프로로콜의 체계 AF_INET은 IPv4 인터넷 프로토콜 체계를 의미

TCP/UDP 프로토콜 사용을 위한 설정

사용할  프로토콜 주소 체계 소켓 타입
TCP AF_INET 또는
AF_INET6
SOCK_STREAM
UDP SOCK_DGRAM
사용할 프로토콜 주소 체계 소켓 타입 프로토콜
TCP AF_INET 또는
AF_INET6
SOCK_STREAM IPPROTO_TCP
UDP SOCK_DGRAM IPPROTO_UDP
사용할 프로토콜 주소 체계 소켓 타입 프로토콜
TCP AF_INET 또는
AF_INET6
SOCK_STREAM 0
UDP SOCK_DGRAM 0
  • BTHPROTO_RFCOMM : 블루투스 통신을 위해 사용, SOCK_STREAM타입과 같이 사용함

소켓 닫기

/*	Windows		*/
#include <winsock2.h>

int closesocket(
	SOCKET s
)
// 성공 : 0
// 실패 : SOCKET_ERROR
/*	Linux	*/
#include <unistd.h>

int close(
	int fd
);

// 성공 : 0
// 실패 : -1
  • 소켓을 닫고 관련 리소스를 운영체제에 반환한다

initSocket.cpp

int main (){
	// ========== 윈속 초기화 ==========
	WSADATA wsa;
	if(WSAStartup(MAKEWORD(2,2), &wsa) != 0 )
		retunr 1;
	printf("[알림] 윈속 초기화 성공!!\n");

	// ========== 소켓 생성 ==========
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);	// IPv4의 TCP통신 
	if(sock == INVALID) err_quit("socket()");
	printf("[알림] 소켓 생성 성공!!\n");

	// ========== 통신 ==========
    
	// ========== 소켓 닫기 ==========
	closesocket(sock);

	// ========== 윈속 종료 ==========
	WSACleanup();
	return 0;
}

연습문제

  1. Initsocket을 수정하여  UDP 소켓 생성!!(2번)
  2. Initscok을 수정하여 IPv6프로토콜 기반으로 TCP 소켓 생성!!(3번)
  3. Initscok을 수정하여 블루투스 소켓 생성!!(블루투스)

initSocket.cpp