//这是一个winsock异步编程的例子
//这个服务监听1000端口,可以使用 telnet localhost 1000进行测试,最大允许20个连接
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "WS2_32.LIB")
#define MAX_SOCKETS 20
#define MAX_BACKLOG 1
#define PORT 1000
SOCKET Startlisten(int port)
{
WORD wVersion=MAKEWORD(2,0);
WSADATA wsData;
int nResult= WSAStartup(wVersion,&wsData);
if(nResult !=0)
{
return 0;
}
SOCKET sock=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sock==INVALID_SOCKET)
{
return 0;
}
sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port= htons(port); //保证字节顺序
addr.sin_addr.s_addr= htonl(INADDR_ANY);
nResult=bind(sock,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult==SOCKET_ERROR)
{
return 0;
}
nResult=listen(sock,MAX_BACKLOG); //最多 MAX_BACKLOG 个 Pending 连接
if(nResult==SOCKET_ERROR)
{
return 0;
}
printf("Please try: telnet localhost 1000\n");
return sock;
}
int main()
{
//init winsock env
WORD wVersion=MAKEWORD(2,0);
WSADATA wsData;
int nResult= WSAStartup(wVersion,&wsData);
//create the first event
WSAEVENT eventList[MAX_SOCKETS+1];
int eventIndex=0;
eventList[eventIndex]=WSACreateEvent();
//start listen on 1000
SOCKET sockList[MAX_SOCKETS+1];
sockList[eventIndex]=Startlisten(PORT);
//use WSAEventSelect to set the server to running on async mode
int rc = WSAEventSelect(sockList[eventIndex], eventList[eventIndex], FD_READ|FD_WRITE|FD_ACCEPT|FD_CLOSE|FD_CONNECT);
int index;
sockaddr_in client;
//waiting on the events to deal with connect requests or network read event
while( (index=WSAWaitForMultipleEvents(eventIndex+1,eventList,false,WSA_INFINITE,true)) != WSA_WAIT_FAILED)
{
index -= WSA_WAIT_EVENT_0;
WSANETWORKEVENTS type;
WSAEnumNetworkEvents(sockList[index],eventList[index],&type);
switch(type.lNetworkEvents)
{
case FD_ACCEPT:
{
int len=sizeof(sockaddr);
if (eventIndex < MAX_SOCKETS)
{
++eventIndex;
sockList[eventIndex] =accept(sockList[index],(sockaddr*)&client,&len);
eventList[eventIndex]=WSACreateEvent();
rc = WSAEventSelect(sockList[eventIndex], eventList[eventIndex], FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT);
printf("connected from %s:%d\n",inet_ntoa( client.sin_addr ),client.sin_port);
}
}
break;
case FD_READ:
{
char mess;
rc =recv(sockList[index],&mess,1,0);
//ctrl+c == 3
if (mess == 3 || rc ==SOCKET_ERROR)
{
shutdown(sockList[index],SD_SEND);
break;
}
rc=send(sockList[index],&mess,sizeof(mess),0);
printf("%c",mess);
}
break;
case FD_WRITE:
{
char buf[256];
sprintf(buf,"hello,you are the %d client.\n",eventIndex);
rc=send(sockList[index],buf,strlen(buf),0);
}
break;
case FD_CLOSE:
{
int len=sizeof(sockaddr);
getpeername(sockList[index],(sockaddr*)&client,&len);
printf("Closed from %s:%d\n",inet_ntoa( client.sin_addr ),client.sin_port);
closesocket(sockList[index]);
}
break;
}
}
return 0;
}