SPRING :: NOTE

[C] 비동기식 에코 서버 본문

Development Language/C · C++ · MFC

[C] 비동기식 에코 서버

RAYZIE 2016. 6. 9. 18:03
반응형
#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
반응형
Comments