SPRING :: NOTE
[C] 비동기식 에코 서버 본문
반응형
#include
#include
#include
#define BUF_SIZE 100
#define PORT 3000
#pragma comment(lib, "ws2_32.lib")
void CompressSockets(SOCKET hSockArray[], int idx, int total);
void CompressEvents(WSAEVENT hEventArr[], int idx, int total);
void ErrorHandling(char* message);
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAdr, clntAdr;
SOCKET hSockArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT hEventArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT newEvent;
WSANETWORKEVENTS netEvents;
int numOfClntSock = 0;
int strLen, i;
int posInfo, startIdx;
int clntAdrLen;
char msg[BUF_SIZE];
/*
if (argc != 2)
{
printf("Usage : %s \n", argv[0]);
exit(1);
}
*/
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error");
hServSock = socket(PF_INET, SOCK_STREAM, 0);
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(PORT);
if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error");
if (listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
newEvent = WSACreateEvent();
if (WSAEventSelect(hServSock, newEvent, FD_ACCEPT) == SOCKET_ERROR)
ErrorHandling("WSAEventSelect() error");
hSockArr[numOfClntSock] = hServSock;
hEventArr[numOfClntSock] = newEvent;
numOfClntSock++;
while (1)
{
posInfo = WSAWaitForMultipleEvents(numOfClntSock, hEventArr, true, WSA_INFINITE, false);
startIdx = posInfo - WSA_WAIT_EVENT_0;
for (i = startIdx; i < numOfClntSock; i++)
{
int sigEventIdx =
WSAWaitForMultipleEvents(1, &hEventArr[i], true, 0, false);
if ((sigEventIdx = WSA_WAIT_FAILED || sigEventIdx == WSA_WAIT_TIMEOUT))
{
continue;
}
else
{
sigEventIdx = i;
WSAEnumNetworkEvents(hSockArr[sigEventIdx], hEventArr[sigEventIdx], &netEvents);
if (netEvents.lNetworkEvents & FD_ACCEPT_BIT) // 연결 요청시
{
puts("Acept Error");
break;
}
clntAdrLen = sizeof(clntAdr);
hClntSock = accept(hSockArr[sigEventIdx], (SOCKADDR*)&clntAdr, &clntAdrLen);
newEvent = WSACreateEvent();
WSAEventSelect(hClntSock, newEvent, FD_READ | FD_CLOSE);
hEventArr[numOfClntSock] = newEvent;
hSockArr[numOfClntSock] = hClntSock;
numOfClntSock++;
puts("connected new client...");
}
if (netEvents.lNetworkEvents & FD_READ) // 데이터 수신 시
{
if (netEvents.iErrorCode[FD_READ_BIT] != 0)
{
puts("Read error");
break;
}//if문 끝
strLen = recv(hSockArr[sigEventIdx], msg, sizeof(msg), 0);
send(hSockArr[sigEventIdx], msg, strLen, 0);
}//if문 끝
if (netEvents.lNetworkEvents & FD_CLOSE) // 종료 요청 시
{
if (netEvents.iErrorCode[FD_CLOSE_BIT] != 0)
{
puts("Close error");
break;
}// if문 끝
WSACloseEvent(hEventArr[sigEventIdx]);
closesocket(hSockArr[sigEventIdx]);
numOfClntSock--;
CompressSockets(hSockArr, sigEventIdx, numOfClntSock);
CompressEvents(hEventArr, sigEventIdx, numOfClntSock);
}//if문 끝
}
}
WSACleanup();
return 0;
}// end of main function
void CompressSockets(SOCKET hEventArr[], int idx, int total)
{
int i;
for (i = idx; i
반응형
'Development Language > C · C++ · MFC' 카테고리의 다른 글
[C] winsock2 사용 시 에러 발생 (1) | 2016.06.09 |
---|---|
[C] inet_addr C4996 에러 (0) | 2016.06.09 |
[C] 윈도우 기반 서버/클라이언트 예제 (0) | 2016.06.09 |
[C] 포인터 예제 소스 및 설명 (1) | 2016.06.09 |
[C/C++] for문을 이용하여 혼자 이동하는 문자만들기 (0) | 2016.06.09 |
Comments