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;
}
연습문제
- Initsocket을 수정하여 UDP 소켓 생성!!(2번)
- Initscok을 수정하여 IPv6프로토콜 기반으로 TCP 소켓 생성!!(3번)
- Initscok을 수정하여 블루투스 소켓 생성!!(블루투스)
'개인 공부 > 네트워크' 카테고리의 다른 글
네트워크P-006 (데이터 전송 방식) (1) | 2023.04.13 |
---|---|
네트워크P-005(TCP Server, TCP Client ) (2) | 2023.04.12 |
네트워크P-004(소켓 구조체 & 바이트 정렬) (0) | 2023.04.10 |
네트워크P-002(네트워크 모델 & Socket) (0) | 2023.04.09 |
네트워크P-001(TCP/IP) (0) | 2023.04.05 |