#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma comment(lib,"ws2_32")
// 에러메세지를 띄우고 화면을 종료하는 함수
void err_quit(const char* msg) {
LPVOID lpMsgBuf;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(char *)&lpMsgBuf, 0, NULL);
MessageBoxA(NULL, (const char*)lpMsgBuf, msg, MB_ICONERROR);
LocalFree(lpMsgBuf);
exit(1);
}
// 에러메세지를 띄우는 함수
void err_display(const char* msg) {
LPVOID lpMsgBuf;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(char *)&lpMsgBuf, 0, NULL);
printf("[%s] %s\n", msg, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
void err_quit(const char *msg)
{
char *msgbuf = strerror(errno);
printf("[%s] %s\n" , msg, msgbuf);
exit(1);
}
void err_display(const char *msg)
{
char *msgbuf = strerror(errno);
printf("[%s] %s\n" , msg, msgbuf);
}
윈도우에서는 소켓 생성 전에 윈속 초기화와 소켓 닫기 후에 윈속 종료 단계가 더 필요하다.
# include <winsock2.h>
// 프로그램 시작
int WSAStartup(
WORD wVersionRequested, // 프로그램이 요구하는 최상위 윈속 버전
LPWSADATA lpWSAData // 윈도우 운영체제가 제공하는 윈속 구현에 관한 정보
);
// 프로그램 종료
int WSACleanup(void);
# include "..\..\Common.h"
it main(int argc, char *argv[])
{
// 윈속 초기화
WSADATA wsa;
if(WSAStartup(MAKEWORD(2,2), &wsa) !=0) // 윈속 초기화가 실패(0이 아니라면) 한다면
return 1; // 1 반환
printf("[알림] 윈속 초기화 성공\n");
// 윈속 종료
WSACleanup();
return 0;
}
윈도우에서는 윈속 초기화를 먼저 해야하지만, 리눅스에서는 별도의 초기화 과정 없이 곧바로 소켓을 만들 수 있다.
소켓을 사용해 통신을 하려면 통신 양단이 같은 프로토콜을 사용해야함 (TCP, UDP)
socket() 함수는 사용자가 요청한 프로토콜을 사용해 통신할 수 있도록 내부적으로 리소스를 할당하고, 이에 접근할 수 있는 일종의 핸들값을 리턴한다. → 소켓 디스크립터
윈도우
#include <winsock2.h>
SOCKET socket(
int af, // 주소 체계 타입
int type, // 소켓 타입 지정
int protocol // 사용할 프로토콜 지정
);
리눅스
#include <sys/types.h>
#include <sys/socket.h>
int socket(
int domain, // 주소 체계 타입
int type, // 소켓 타입 지정
int protocol // 사용할 프로토콜 지정
);
소켓은 사용한 통신을 마치면 관련 리소스를 반환해야한다.
closesocket() 또는 close() 사용
윈도우
#include <winsock2.h>
int closesocket(SOCKET s);
리눅스
#include <unistd.h>
int close(int fd);
#include "V.Common.h"
int main(int argc, char *argv[]) {
// 윈속 초기화
WSADATA wsa;
// 윈속 초기화 확인
if(WSAStartup(MAKEWORD(2,2) , &wsa) !=0)
return 1; // 초기화 실패 시 프로그램 종료
printf("[알림] 윈속 초기화 성공\n");
// 소켓 생성
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_S0CKET) err_quit("socket()");
printf("[알림] 소켓 생성 성공\n");
// 소켓 닫기
closesocket(sock);
// 윈속 종료
WSACleanup();
return 0;
}