디시인사이드 갤러리

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

갤러리 본문 영역

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

미역c(210.119) 2010.10.09 19:34:45
조회 543 추천 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/05/27 - -
220543 원의 주변 좌표를 구하는 수학 공식 홀랑 까먹어서 횽들을 찾음 [13] ㅅㅅ(211.212) 10.11.26 264 0
220542 토렌토 사이트 만들면 잡혀가나연? [6] 홍어(58.180) 10.11.26 132 0
220541 현재 iframe에서 다른 페이지 불러왔는데.. 또 부르면 원래 오류남? [3] 1234(168.131) 10.11.26 41 0
220540 난 갤럭시탭 별로던데.. [2] ㄹㄹ(168.131) 10.11.26 127 0
220539 갤릭시 탭 이가격에파냐?.jpg ㅇㅇ(118.36) 10.11.26 151 0
220534 연평도에서 또 미사일 소리가 들렸다는데? [3] 보통날(112.216) 10.11.26 141 0
220533 영수증사진 [29] (220.121) 10.11.26 280 0
220531 니들도 이런적 있냐? [5] ㄹㄹ(168.131) 10.11.26 104 0
220530 컴공은 좆망트리다. [11] 미친넘(220.67) 10.11.26 441 0
220528 수능끝나고 C언어에 입갤했습니다. [2] 뭐지(114.200) 10.11.26 108 0
220527 안녕하세요 뭐든지 제작해드립니다. [2] 초고수(211.205) 10.11.26 102 0
220526 이번 Java 우리학교 기말 과제가 프로그램 소스 하나 가져와서 설명하는 [8] 공대생(218.154) 10.11.26 155 0
220524 누가 전태일처럼 희생좀 해라. [2] 미친넘(220.67) 10.11.26 133 0
220522 퀵베이직 소스를 비베6.0버전으로 바꿔주실 용사(100만원) [11] (220.121) 10.11.26 217 0
220520 C++ 질문입니다 횽들. [6] ㅉㅉㅉ(59.10) 10.11.26 99 0
220513 이바보 보면 생각나는 글 [5] 보통날(112.216) 10.11.26 84 0
220511 이클립스 인텔리센스 질문 좀 [2] ㅂㄷㄱ(121.155) 10.11.26 115 0
220510 요새 윈도우로 웹 서핑 거의 안 함 [4] 분당살람갤로그로 이동합니다. 10.11.26 104 0
220508 iframe 한번은 된다 치고... 두번하면 null 임. [5] ㅇㄹ(168.131) 10.11.26 115 0
220507 아이프레임 도와줭.. [11] ㅇㄹ(168.131) 10.11.26 96 0
220504 난 ie 써도 아무문제없다- [10] 개쉛기갤로그로 이동합니다. 10.11.26 102 0
220502 파폭은 그래도 괜찮지않나요 ㅇㅇ [12] 나는scv갤로그로 이동합니다. 10.11.26 104 0
220499 아마추어가 독학으로 쇼핑몰 홈페이지 만들려면? [4] 52(219.251) 10.11.26 202 0
220491 프로그래머 형님들 좀 봐주삼. 나 지금 진지함 [10] 연대생(211.253) 10.11.26 193 0
220490 mfc에서 구조체 하나 전역으로 쓰고싶은데열 [3] 르하소갤로그로 이동합니다. 10.11.26 152 0
220488 자바 너무 어려워서 포기하고 싶군요.. [5] ss(175.197) 10.11.26 144 0
220483 횽들아 학창시절 선생님을 좋아해본적 있니 [19] 해일리갤로그로 이동합니다. 10.11.26 136 0
220482 C++ 간단한 질문좀 할께 횽들. [13] ㅉㅉㅉ(59.10) 10.11.26 121 0
220481 USB to Parallel Converter [3] 개로그(121.159) 10.11.26 129 0
220479 char배열 에서 문자열 찾아주는 함수-.- [6] 르하소갤로그로 이동합니다. 10.11.26 122 0
220478 프갤을 불타오르게 만들 떡밥 [4] 김남풍(121.182) 10.11.26 126 0
220477 소켓으로 바이너리 데이터 수신할때.. [3] 르하소갤로그로 이동합니다. 10.11.26 92 0
220476 횽들 쥰나 급함 ㅠㅠ 헬프미 [3] 허허벌판갤로그로 이동합니다. 10.11.26 78 0
220475 파일을 코드 그대로 보여주는거 없음? [5] 르하소갤로그로 이동합니다. 10.11.26 87 0
220474 우리나라 게임 프로그래머의 인원수!! [5] 01의조화(121.138) 10.11.26 249 0
220473 프갤러님드라 자바 이부분 막히는데 쪼끔만바죵 [10] 으으(220.149) 10.11.26 118 0
220472 나도 사수따라 지를거임 [2] 개쉛기갤로그로 이동합니다. 10.11.26 151 0
220467 크으... G27 짱 조음...ㅠ [7] 아주아슬갤로그로 이동합니다. 10.11.26 149 0
220466 MFC에서 파일 일부분만 지우고 싶을때.. [4] 르하소갤로그로 이동합니다. 10.11.26 83 0
220462 리눅스 프로그래머가 돈을 못버는 이유가 [6] =\\(203.93) 10.11.26 262 0
220461 아이프레임 접근 에러.. 자세한거 [9] ㅇㅇ?(168.131) 10.11.26 120 0
220459 일반인 토니스타크 [7] 르하소갤로그로 이동합니다. 10.11.26 196 0
220458 싸우지마 ㅠㅠ [4] Ordinary Day갤로그로 이동합니다. 10.11.26 100 0
220456 아이프레임 접근은 어떻게?? [7] ㅇㅇ?(168.131) 10.11.26 102 0
220455 야동 확실히 숨기는 방법 [6] .3(124.137) 10.11.26 187 0
220447 컴퓨터 고쳐주세요 [15] 프덕프덕(92.2) 10.11.26 146 0
220444 OOP에서 포인터사용은 지양해야되는거 아님? [8] 르하소갤로그로 이동합니다. 10.11.26 143 0
220442 인셉션 재밌따. [4] Gromit갤로그로 이동합니다. 10.11.26 94 0
220441 프로그래밍 과외 할려는데 [3] MK(118.36) 10.11.26 137 0
220440 php덩어리 페이스북이 마소랑 어깨를 나란히 한댄다.. [2] 홍어(219.251) 10.11.26 137 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2