서버
#include<WinSock2.h>
#include<mswsock.h>
#include<ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
void HandleError(const char* cause)
{
int32 err = WSAGetLastError();
cout << cause << err << " : error exists";
}
int main()
{
WSADATA wsaData;
int32 err;
err = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
{
cout << "Winsock Initialize Failed\n" << err << " : error exists";
return 0;
}
// 블로킹
// accept -> 접속한 클라가 있을 때 성공
// connect -> 클라가 접속에 성공했을 때
// send sentto -> 요청한 데이터를 송신 버퍼에 복사했을 때
// recv recvfrom -> 수신 버퍼에 있는 내용을 유저 레벨 버퍼에 복사했을 때
// 논블로킹
SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET)
{
HandleError("Socket Failed");
return 0;
}
u_long on = 1;
if (::ioctlsocket(listenSocket, FIONBIO, &on) == INVALID_SOCKET)
{
HandleError("Nonblocking Socket Failed");
return 0;
}
SOCKADDR_IN serverAddr;
::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = ::htonl(INADDR_ANY);
serverAddr.sin_port = ::htons(7777);
err = ::bind(listenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
if (err == SOCKET_ERROR)
{
HandleError("Bind failed");
return 0;
}
err = ::listen(listenSocket, 15);
if (err == SOCKET_ERROR)
{
HandleError("Listen failed");
return 0;
}
cout << "Accept" << endl;
SOCKADDR_IN clientAddr;
::memset(&clientAddr, 0, sizeof(clientAddr));
int addrLen = sizeof(clientAddr);
// Accept
while (true)
{
SOCKET clientSocket = ::accept(listenSocket, (SOCKADDR*)&clientAddr, &addrLen);
if (clientSocket == INVALID_SOCKET)
{
// 원래 블록해야할 .. 너가 논 블로킹으로 하라메
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
// Error
break;
}
cout << "Client Connected!" << endl;
while (true)
{
char recvBuffer[1000];
int32 recvLen = ::recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (recvLen == SOCKET_ERROR)
{
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
break;
}
else if (recvLen == 0)
{
break;
}
cout << "Recv Data Len = " << recvLen << endl;
// send
while (true)
{
err = ::send(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (err == SOCKET_ERROR)
{
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
break;
}
cout << "Send Data! Len = " << recvLen << endl;
break;
}
}
}
// 소켓 리소스 반환
::closesocket(listenSocket);
// winsock 해제
::WSACleanup();
return 0;
}
클라이언트
#include <WinSock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
void HandleError(const char* cause)
{
int32 err = WSAGetLastError();
cout << cause << err << " : error exists";
}
int main()
{
WSADATA wsaData;
int32 err;
err = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
{
cout << "Winsock Initialize Failed\n" << err << " : error exists";
return 0;
}
SOCKET clientSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == INVALID_SOCKET)
{
HandleError("Socket Failed");
return 0;
}
u_long on = 1;
if (::ioctlsocket(clientSocket, FIONBIO, &on) == INVALID_SOCKET)
{
HandleError("Nonblocking Socket Failed");
return 0;
}
SOCKADDR_IN serverAddr;
::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
::inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);
serverAddr.sin_port = ::htons(7777);
while (true)
{
err = ::connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
if (err == SOCKET_ERROR)
{
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
if (::WSAGetLastError() == WSAEISCONN)
break;
break;
}
}
cout << "Connecting Server!\n";
char sendBuffer[1000] = "Hello World!";
while (true)
{
err = ::send(clientSocket, sendBuffer, sizeof(sendBuffer), 0);
if (err == SOCKET_ERROR)
{
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
break;
}
cout << "Send Data! Len = " << sizeof(sendBuffer) << endl;
while (true)
{
char recvBuffer[1000];
err = ::recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (err == SOCKET_ERROR)
{
if (::WSAGetLastError() == WSAEWOULDBLOCK)
continue;
break;
}
else if (err == 0)
{
break;
}
cout << "Recv Data! Len = " << sizeof(sendBuffer) << endl;
cout << "Recv Data = " << recvBuffer << endl;
break;
}
this_thread::sleep_for(1s);
}
// winsock 해제
::WSACleanup();
}
Non_blocking socket Setting
u_long on = 1;
if (::ioctlsocket(listenSocket, FIONBIO, &on) == INVALID_SOCKET)
{
HandleError("Nonblocking Socket Failed");
return 0;
}
Non_blocking Error
::WSAGetLastError() == WSAEWOULDBLOCK