// inet_addr()함수는 현재 Deprecated.
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#pragma comment (lib, "Ws2_32.lib")
int main()
{
WSADATA wsa;
// WSAStartup : Winsock DLL을 시작하는 함수
// MAKEWORD WORD 생성 Macro
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
return 0;
}
// TCP
//SOCKET sock1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// UDP
//SOCKET sock2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// 마지막 옵션을 0으로 설정함으로써 TCP/UDP 모두 사용 가능
SOCKET sock3 = socket(AF_INET, SOCK_STREAM, 0);
// client
SOCKADDR_IN sa;
sa.sin_family = AF_INET; // IP 주소 체계. PF_INET도 있음, 그 외 IPX, UNIT 등 존재
sa.sin_addr.s_addr = inet_addr("192.168.0.12"); // string을 byte로 변환하는 함수. Deprecated 됨
sa.sin_port = htons(10000); // host to network short. 엔디안 정렬 함수. ntohs, ntohl, htonl 등이 있음
int iRet = connect(sock3, (sockaddr*)&sa, sizeof(sa));
if (iRet == SOCKET_ERROR)
{
return 1;
}
// Server
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY); // 지정된 Port로부터 연결 요청이 오는 모든 Address
sa.sin_port = htons(10000);
int iRet = bind(sock3, (sockaddr*)&sa, sizeof(sa));
if (iRet == SOCKET_ERROR)
{
return 1;
}
iRet = listen(sock3, SOMAXCONN); // 최대 연결, 운영체제별로 값이 다른듯
if (iRet == SOCKET_ERROR)
{
return 1;
}
u_long iMode = TRUE;
// Socket의 Blocking-non Blocking mode 설정
// FIONBIO : Blocking-Non Blocking설정 시 필요하다고는 하는데 의미는 모르겠음
// mode값을 통해 Block-Non Block설정 가능
ioctlsocket(sock3, FIONBIO, &iMode);
while (1)
{
char szSendMsg[256] = { 0, };
printf("%s", "send---->");
fgets(szSendMsg, 256, stdin);
int iSendBytes = send(sock3, szSendMsg, strlen(szSendMsg), 0);
if (iSendBytes == SOCKET_ERROR)
{
// WSAEWOULDBLOCK : Non-Blocking Socket의 명령이 즉각 수행될 수 없을 때 설정되는 값
// 공식 문서에 따르면 '이는 모드로 인해 호출이 즉시 반환되지 않았다면 차단되었을 것임을 나타냅니다.'
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
closesocket(sock3);
return 1;
}
continue;
}
char szRecvMsg[256] = { 0, };
int iRecvBytes = recv(sock3, szRecvMsg, 256, 0);
if (iRecvBytes == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
closesocket(sock3);
return 1;
}
continue;
}
}
// Socket은 File과 마찬가지로 open-close를 꼭 수행해야 함
closesocket(sock3);
WSACleanup();
}
Blocking-Non Blocking은 동기화와는 다른 개념
비동기화는 함수가 끝나지 않았음에도 함수 밖으로 나오는 것을 의미
Non Blocking은 Background에서 함수의 연산이 돌지 않음
Non-Blocking Socket의 명령이 즉각 수행될 수 없을 때 설정되는 값
공식 문서에 따르면 '이는 모드로 인해 호출이 즉시 반환되지 않았다면 차단되었을 것임을 나타냅니다.'
Windows OS에서는 Socket마다 RW Buffer를 제공하며 이 RW Buffer에 데이터가 저장되었느냐 여부에 따라 send, recv의 반환