디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

IOCP WSAEVENT 배열과 소켓배열을 이용하는 모델

미역c(210.119) 2010.10.09 19:34:45
조회 544 추천 0 댓글 1

횽들 IOCP 콜백함수 사용하는거 말고 이벤트를 사용하는 IOCP
예제를 따라 치고 있는데 말이야.
main 함수에서 더미 이벤트(WSAEVENT)를 하나 추가하는데 
책에선 이게 특별한 일을 위해서 추가 한다고 했는데
정확하게 무슨 일은 하는지 는 안나와있네..; 무슨일을해?


소스는 여기에..다 친게 아니라서 돌아가진않아.;

#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment (lib, "ws2_32.lib")

const int BUFSIZE = 512;

struct SOCKETINFO
{
        SOCKET sock;
        int recvbytes;
        int sendbytes;
        WSAOVERLAPPED overlapped;
        WSABUF wsabuf;
        char buf [BUFSIZE+1];
};
SOCKETINFO * SocketInfoArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT EventArr[WSA_MAXIMUM_WAIT_EVENTS];
int nTotalSockets = 0;
CRITICAL_SECTION cs;

DWORD WINAPI WorkerThread(LPVOID pParam);
BOOL AddSocketInfo(SOCKET sock);
void RemoveSocketInfo(int nIndex);
void err_display(char * msg);
void err_quit(char * msg);

int main()
{
        int retval;
        InitializeCriticalSection(&cs);

        WSADATA wsa;
        if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
                return -1;

        SOCKET listen_sock, client_sock;
        SOCKADDR_IN serveraddr, clientaddr;
        int addrlen = sizeof(clientaddr);

        listen_sock = socket(AF_INET, SOCK_STREAM, 0);
        if(listen_sock == INVALID_SOCKET)
                err_quit("socket()");

        ZeroMemory(&serveraddr,sizeof(serveraddr));
        serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(9990);

        retval = bind(listen_sock, (SOCKADDR*) &serveraddr, sizeof(serveraddr));
        if(retval == SOCKET_ERROR)
                err_quit("bind()");

        retval = listen(listen_sock, SOMAXCONN);
        if(retval == SOCKET_ERROR)
                err_quit("listen()");
        //특별한 일을 하는 이벤트(?) ......아놔 . ㅋㅋㅋ
        WSAEVENT hEvent = WSACreateEvent();
        if(hEvent == WSA_INVALID_EVENT)
                err_quit("WSACreateEvent()");

        EventArr[nTotalSockets++] = hEvent;

        DWORD dwThreadId;
        HANDLE hThread = CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
        if(hThread == NULL)
                err_quit("CreateThread()");

        while(1){
                client_sock = accept(listen_sock, (SOCKADDR*) &clientaddr, &addrlen);
                if(client_sock == INVALID_SOCKET){
                        err_display("accept()");
                        continue;
                }
                if(AddSocketInfo(client_sock) == FALSE){
                        closesocket(client_sock);
                        continue;
                }
                printf("[TCP 서버] 클라이언트 접속 : %s %d \\n",inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));

                SOCKETINFO * ptr = SocketInfoArr[nTotalSockets-1];
                DWORD recvbytes;
                DWORD flags = 0;

                retval = WSARecv(ptr->sock, &(ptr->wsabuf), 1, &recvbytes, &flags, &(ptr->overlapped), NULL);
                if(retval == SOCKET_ERROR){
                        if(WSAGetLastError() != WSA_IO_PENDING){
                                err_display("WSARecv()");
                                RemoveSocketInfo(nTotalSocket-1);
                                continue;
                        }
                }
                if(WSASetEvent(EventArr[0]) == FALSE){
                        err_display("WSASetEvent()");
                        break;
                }
        }
        WSACleanup();
        DeleteCriticalSection(&cs);
        return 0;
}

DWORD WINAPI WorkerThread(LPVOID pParam)
{
        int retval;
        
        while(1){
                DWORD index = WSAWaitForMultipleEvents(nTotalSockets, EventArr, FALSE, WSA_INFINITE, FALSE);
                if(index == WSA_WAIT_FAILED){
                        err_display("WSAWaitForMultipleEvents()");
                        continue;
                }
                index -= WSA_WAIT_EVENT_0;
                WSAResetEvent(EventArr[index]);
                if(index == 0)
                        continue;
                
                SOCKETINFO * ptr = SocketInfoArr[index];
                SOCKADDR_IN clientaddr;
                int addrlen = sizeof(clientaddr);
                getpeername(ptr->sock, (SOCKADDR*) &clientaddr, &addrlen);

                DWORD cbTrans, flags;
                retval = WSAGetOverlappedResult(ptr->sock, &(ptr->overlapped), &cbTrans, FALSE, &flags);
                if(retval == FALSE || cbTrans == 0){
                        if(retval == FALSE)
                                err_display("WSAGetOverlappedResult()");
                        RemoveSocketInfo(index);
                        printf("[TCP서버] 클라이언트 종료 : %s %d\\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                        continue;
                }
                
                if(ptr->recvbytes == 0){
                        ptr->recvbytes = cbTrans;
                        ptr->sendbytes = 0;
                        ptr->buf[ptr->recvbytes] = \'\\0\';
                        printf("[TCP/%s:%d] %s \\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), ptr->buf);
                }
                else
                        ptr->sendbytes += cbTrans;
                
                if(ptr->recvbytes > ptr->sendbytes){
                        ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
                        ptr->overlapped.hEvent = EventArr[index];
                        ptr->wsabuf.buf = ptr->buf + ptr->sendbytes;
                        ptr->wsabuf.len = ptr->recvbytes - ptr->sendbytes;

                        DWORD sendbytes;
                        retval = WSASend(ptr->sock, &(ptr->wsabuf), 1, &sendbytes, 0 , &(ptr->overlapped), NULL);
                        if(retval == SOCKET_ERROR){
                                if(WSAGetLastError() != WSA_IO_PENDING){
                                        err_display("WSASend()");
                                }
                                continue;
                        }
                }
                else{
                        ptr->recvbytes = 0;

                        ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
                        ptr->overlapped.hEvent = EventArr[index];
                        ptr->wsabuf.buf = ptr->buf;
                        ptr->wsabuf.len = BUFSIZE;

                        DWORD recvbytes;
                        flags = 0;

                        retval = WSARecv(ptr->sock, &(ptr->wsabuf), 1, &recvbytes, &flags, &(ptr->overlapped), NULL);
                        if(retval == SOCKET_ERROR){
                                if(WSAGetLastError() != WSA_IO_PENDING){
                                        err_display("WSARecv()");
                                }
                                continue;
                        }
                }
        }
}

BOOL AddSocketInfo(SOCKET sock)
{
        EnterCriticalSection(&cs);
        if(nTotalSockets >= WSA_MAXIMUM_WAIT_EVENTS){
                printf("[오류] 접속 최대수 초과 접속 불가\\n");
                LeaveCriticalSection(&cs);
                return FALSE;
        }
        SOCKETINFO * ptr = new SOCKETINFO;
        if(ptr == NULL){
                printf("[오류] 메모리 부족!!\\n");
                delete ptr;
                LeaveCriticalSection(&cs);
                return FALSE;
        }
        WSAEVENT hEvent = WSACreateEvent();
        if(hEvent == WSA_INVALID_EVENT){
                err_display("WSACreatEvent()");
                delete ptr;
                LeaveCriticalSection(&cs);
                return FALSE;
        }

        ::ZeroMemory(&(ptr->overlapped), sizeof(ptr->overlapped));
        ptr->sock = sock;
        ptr->recvbytes = 0;
        ptr->sendbytes = 0;
        ptr->wsabuf.buf = ptr->buf;
        ptr->wsabuf.len = BUFSIZE;
        SocketInfoArr[nTotalSockets] = ptr;
        EventArr[nTotalSockets] = hEvent;
        ptr->overlapped.hEvent = EventArr[nTotalSockets];
        nTotalSockets++;

        LeaveCriticalSection(&cs);
        return TRUE:
}
        
void RemoveSocketInfo(int nIndex)
{
        EnterCriticalSection(&cs);
        SOCKETINFO * ptr = SocketInfoArr[nIndex];
        closesocket(ptr->sock);
        delete ptr;
        WSACloseEvent(EventArray[index]);

        for(int i=index;i<nTotalSocket;i++){
                SocketInfoArr[i] = SocketInfoArr[i+1];
                EventArr[i] = EventArr[i+1];
        }
        nTotalSocket--;

        LeaveCriticalSection(&cs);

}

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 힘들게 성공한 만큼 절대 논란 안 만들 것 같은 스타는? 운영자 24/06/10 - -
224121 캠퍼스 커플 해본사람 있습니까? 그거 어떻죠? [13] 금호족기(61.75) 10.12.11 125 0
224120 이더넷 궁금해요. [10] 저격곰팡이갤로그로 이동합니다. 10.12.11 86 0
224119 안드로이드 폰 어플 개발해보고 싶은 뉴비입니다. [24] 알바즐갤로그로 이동합니다. 10.12.11 269 0
224118 eclipse test코드 써본사람~ [1] 황태자갤로그로 이동합니다. 10.12.11 43 0
224117 리눅스에 C언어코드에 색상넣을려면 어떻게해야함. [2] 마타버터갤로그로 이동합니다. 10.12.11 90 0
224116 형들 비베말야.ㅂ [8] 킁봑(112.171) 10.12.11 89 0
224115 밥먹었어? [4] elwlwlwk갤로그로 이동합니다. 10.12.11 92 0
224114 플로이드알고리즘이 최적이 원리가성립되는걸어케알까요?ㅋㅋ [1] 알고리즘ㅠ(59.25) 10.12.11 171 0
224113 8시간 30분.... [1] 권혁진(58.233) 10.12.11 55 0
224112 시험 망했다 \(^0^)/ [4] Rei@디씨갤로그로 이동합니다. 10.12.11 100 0
224111 촘 조용하다 오늘? [1] 땡칠도사갤로그로 이동합니다. 10.12.11 82 0
224110 노트북이 부서졌다...ㅠㅠ [9] Rei@디씨갤로그로 이동합니다. 10.12.11 194 0
224109 동적할당해서 도서관 프로그램 소스공개 [1] 꿀레갤로그로 이동합니다. 10.12.11 124 0
224107 코드를 직관적으로 짜는 게 좋은거야? [5] 노력하는초보갤로그로 이동합니다. 10.12.11 103 0
224106 요즘 갤에 잦뉴비들이 유난히 설치는거 같다 [6] Heimdal(121.185) 10.12.11 131 0
224105 c언어 코딩좀 제발부탁드려요ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ [6] 코딩(183.109) 10.12.11 119 0
224103 예비고3 실업계생인데요 [3] 응잉잉(221.155) 10.12.11 85 0
224101 c언어 프로젝트 코딩좀 해주세요 [11] 코딩(183.109) 10.12.11 195 0
224100 야이 싯팔 숙제갤러색히들아 [7] printf(115.93) 10.12.11 110 0
224099 혹시 이거 아는 사람 있어? [3] 빨리빨리(58.140) 10.12.11 117 0
224097 형들 쪽팔리지만 질문 좀 할게(숙제아님) [12] printf(115.93) 10.12.11 156 0
224096 C언어 공용체 이거 원리가 뭐야. [5] (168.131) 10.12.11 134 0
224095 c언어 실력 '상' 급 될려면 c언어 몇 년 파야 되나요??? [11] 컴돌이(58.77) 10.12.11 409 0
224094 자 토요일이라.. [1] 홍어(218.51) 10.12.11 41 0
224093 난 지금 뭔가가 크게 잘못되어 있어 도와줘 [4] 십ㄹㄹ바(211.192) 10.12.11 104 0
224092 MFC질문좀..ㅠㅠ... [4] ㄴㄴ(220.69) 10.12.11 76 0
224091 이거 왜 아웃풋이 아무것도 안뜨지? [3] 팔로윌갤로그로 이동합니다. 10.12.11 58 0
224090 세브님 감사 성공했읍니다. 언제 맛있는거라도 대접해드리고싶네요 [5] 장은성(220.121) 10.12.11 94 0
224089 사실 내 롤모델 유리한임 [4] 116.44(116.44) 10.12.11 185 0
224088 뻘소리 [2] prismatic갤로그로 이동합니다. 10.12.11 54 0
224087 vc6.0 과 vs2008 의 차이점 발견. [7] new gay[max](183.105) 10.12.11 332 0
224086 배열의 원소를 하나의 텍스트박스에 모우는 방법좀 [8] 장은성(220.121) 10.12.11 136 0
224085 아이유 dot(121.130) 10.12.11 133 0
224084 치킨먹구싶다 Rei@디씨갤로그로 이동합니다. 10.12.11 105 0
224082 자바는 왜 예외처리를 반드시 해주어야 하냐? [3] ㅁㄷㄹㅇㅊ(123.49) 10.12.11 171 0
224081 술,담배 이런거때문에 니들 뇌성능이 그모양인거다. [5] 홍어(218.51) 10.12.11 154 0
224080 visual studio 2008 에러..이건 도대체 뭔가요 [4] Paradise갤로그로 이동합니다. 10.12.11 137 0
224079 게임관련 일 안하면 winapi안배워도됨?? [1] -.ㅇ(183.101) 10.12.11 139 0
224078 프로그래머로써 머리안좋다고 걱정할꺼없음 꿀레갤로그로 이동합니다. 10.12.11 168 0
224077 횽들.. 플밍 하면서 내 머리가 좋은게 아니구나 라고 느껴본적있어 ? [6] 오..오갱..(112.146) 10.12.11 158 0
224076 우리나라에서 프로그래머가 대우못받는게 진실인가요 찌두(221.155) 10.12.11 116 0
224075 위대하신 프갤년들아, c++은 왜 안된다고 만 하냐? [7] 육체지향언어(183.105) 10.12.11 299 0
224074 아 일하기싫어 꿀레갤로그로 이동합니다. 10.12.11 89 0
224073 나도 요즘 학벌 신경쓰이네... [1] 하앍하앍(123.199) 10.12.11 164 0
224072 임베디드 프로그래밍 공부할려면 돈 많이 듬여? [5] 하앍하앍(123.199) 10.12.11 205 0
224070 Objective C는 아름다운 언어같다. 써니덕후갤로그로 이동합니다. 10.12.11 145 0
224069 구글의 퀴즈 [3] 양반씨갤로그로 이동합니다. 10.12.11 128 0
224068 케이온보니까 고딩때로 돌아가고 싶다. [1] 꿀레갤로그로 이동합니다. 10.12.11 105 0
224067 요새 어디서 듣도 보도 못한 잡놈들이 들어와서 써니덕후갤로그로 이동합니다. 10.12.11 71 0
224065 고칼로리 봐라 [4] 써니덕후갤로그로 이동합니다. 10.12.11 115 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2