#pragma comment(lib,"ws2_32")
#include <winsock2.h>
#include <iostream>
using namespace std;
struct App
{
SOCKET sarr[WSA_MAXIMUM_WAIT_EVENTS]; //WSA_MAXIMUM_WAIT_EVENTS 는 64로 정의되어있다.
HANDLE hEarr[WSA_MAXIMUM_WAIT_EVENTS]; //64는 한 소켓이 소유할 수 있는 이벤트 객체 핸들의 최대갯수
HANDLE hFileArr[WSA_MAXIMUM_WAIT_EVENTS];
int now; //신호상태인 이벤트객체의 갯수
};
App app;
void AcceptProc(int index);
void ReadProc(int index);
void CloseProc(int index);
void main()
{
WSADATA wsadata;
WSAStartup(MAKEWORD(2,2),&wsadata);
SOCKET sock;
sock = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN servaddr={0,};
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.34.103");
servaddr.sin_port = htons(1100);
int re = bind(sock,(SOCKADDR *)&servaddr,sizeof(servaddr));
re = listen(sock,5);
app.sarr[app.now]=sock; //셋팅된 sock을 app.sarr[app.now]에 넣어준다.
app.hEarr[app.now] = WSACreateEvent(); //이벤트객체를 생성
WSAEventSelect(app.sarr[app.now],app.hEarr[app.now],FD_ACCEPT);
//app.sarr[app.now] 에서 FD_ACCEPT가 발생하면 app.hEarr[app.now]를 신호상태로 바꿔준다.
app.now++; //생성됐으니 카운트 증가
WSANETWORKEVENTS ev; //이벤트의 유형정보와 오류정보로 채워질 WSANETWORKEVENTS 구조체 변수
int index;
while(1)
{
index = WSAWaitForMultipleEvents(app.now,app.hEarr,FALSE,WSA_INFINITE,FALSE);
index -= WSA_WAIT_EVENT_0;
//FALSE 이면 이벤트 객체중에서 하나라도 신호상태이면 index를 반환해준다.
//TRUE 이면 전부 신호상태이어야 반환된다.
//2개 이상 신호상태일시 인덱스 번호가 낮은 것이 반환된다.
WSAEnumNetworkEvents(app.sarr[index],app.hEarr[index],&ev);
//이벤트가 발생한 소켓과 신호상태인 이벤트객체핸들에서 발생한이벤트의 유형정보와 오류정보가 WSANETWORKEVENTS 구조체의 주소값으로 전달된다.
switch(ev.lNetworkEvents)
{
case FD_ACCEPT:
AcceptProc(index);
break;
case FD_READ:
ReadProc(index);
break;
case FD_CLOSE:
CloseProc(index);
break;
}
}
WSACleanup();
}
void AcceptProc(int index)
{
SOCKADDR_IN clientaddr;
int len = sizeof(clientaddr);
SOCKET sock = app.sarr[index];
app.sarr[app.now] = accept(sock,(SOCKADDR *)&clientaddr,&len);
app.hEarr[app.now] = WSACreateEvent();
WSAEventSelect(app.sarr[app.now],app.hEarr[app.now],FD_READ|FD_CLOSE);
app.now++;
}
void ReadProc(int index)
{
char buf[100];
SOCKET sock = app.sarr[index];
if(recv(sock,buf,100,0)<=0) //접속이 종료되었거나 에러가 나면 리턴
{
return;
}
printf("%s\n", buf);
}
void CloseProc(int index)
{
WSACloseEvent(app.hEarr[index]);
closesocket(app.sarr[index]);
app.now--;
app.hEarr[index] = app.hEarr[app.now];
app.sarr[index] = app.sarr[app.now];
}
'API & MFC > 네트워크프로그래밍' 카테고리의 다른 글
우아한 종료 (0) | 2010.02.09 |
---|---|
EventSelect(클) (0) | 2010.02.05 |
EventSelect란? (0) | 2010.02.05 |
ASyncSelect 예제 (1) | 2010.02.04 |
소켓통신의 라이브러리 사용 선택 시 고려사항 (0) | 2010.02.02 |