#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
// void main()
// {
// WORD wVersionRequested;
// WSADATA wsaData;
// int err;
//
// wVersionRequested = MAKEWORD( 1, 1 );
//
// err = WSAStartup( wVersionRequested, &wsaData );
// if ( err != 0 ) {
// /* Tell the user that we could not find a usable */
// /* WinSock DLL. */
// return;
// }
//
// /* Confirm that the WinSock DLL supports 2.2.*/
// /* Note that if the DLL supports versions greater */
// /* than 2.2 in addition to 2.2, it will still return */
// /* 2.2 in wVersion since that is the version we */
// /* requested. */
//
// if ( LOBYTE( wsaData.wVersion ) != 1 ||
// HIBYTE( wsaData.wVersion ) != 1 ) {
// /* Tell the user that we could not find a usable */
// /* WinSock DLL. */
// printf("It is not the requested version!");
// WSACleanup( );
// return;
// }
//
// SOCKET socketSrv = socket(AF_INET,SOCK_STREAM,0);
// SOCKADDR_IN addrSrv;
// addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
// addrSrv.sin_family = AF_INET;
// addrSrv.sin_port = htons(6000);
//
// bind(socketSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
// listen(socketSrv,5);
//
// SOCKADDR_IN addrClient;
// int len = sizeof(SOCKADDR);
// while(1)
// {
// SOCKET socketConn = accept(socketSrv,(SOCKADDR*)&addrClient,&len);
// char sendBuf[100];
// sprintf(sendBuf,"Welcome %s to http://hi.baidu.com",inet_ntoa(addrClient.sin_addr));
//
// send(socketConn,sendBuf,strlen(sendBuf)+1,0);
//
// char recvBuf[100];
// recv(socketConn,recvBuf,strlen(recvBuf)+1,0);
// printf("%s\n",recvBuf);
// closesocket(socketConn);
// }
// /* The WinSock DLL is acceptable. Proceed. */
// }
/*事件对象I/O管理程序实例*/
#define WSA_MAXIMUN_EVENTS 64
#define MAX_BUF_LEN 1024
void CompressArrays(int Index, WSAEVENT Event[WSA_MAXIMUM_WAIT_EVENTS],
SOCKET Socket[WSA_MAXIMUM_WAIT_EVENTS],
unsigned long *EventTotal);
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("It is not the requested version!");
WSACleanup( );
return;
}
SOCKET SocketArray[WSA_MAXIMUN_EVENTS];
SOCKET socketSrv = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(socketSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
/*创建一个事件对象*/
WSAEVENT NewEvent = WSACreateEvent();
/*在socketsrv套接字上注册套接连接和关闭的网络事件*/
// WSAEventSelect(socketSrv,NewEvent,FD_ACCEPT|FD_CLOSE);
if (SOCKET_ERROR == WSAEventSelect(socketSrv,NewEvent,FD_ACCEPT|FD_CLOSE))
{
printf("1.WSAEventSelect() failed with error %d\n", WSAGetLastError());
return;
}
listen(socketSrv,5);
WSAEVENT EventArray[WSA_MAXIMUN_EVENTS];
DWORD EventTotal = 0;
SocketArray[EventTotal] = socketSrv;
EventArray[EventTotal] = NewEvent;
EventTotal++;
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
int Index = 0;
WSANETWORKEVENTS NetworkEvents;
while(1)
{
//在所有套接口上等待网络事件的发生
Index = WSAWaitForMultipleEvents(EventTotal,EventArray,FALSE,WSA_INFINITE,FALSE);
WSAEnumNetworkEvents(SocketArray[Index-WSA_WAIT_EVENT_0],
EventArray[Index-WSA_WAIT_EVENT_0],
&NetworkEvents);
//检查FD_ACCEPT网络事件
if(NetworkEvents.lNetworkEvents&FD_ACCEPT)
{
if(0 != NetworkEvents.iErrorCode[FD_ACCEPT_BIT])
{
printf("FD_ACCEPT failed with error %d\n",NetworkEvents.iErrorCode[FD_ACCEPT_BIT]);
break;
}
}
//接受新的连接,并存入套接字数组
SOCKET socketConn = socket(AF_INET,SOCK_STREAM,0);
socketConn = accept(SocketArray[Index-WSA_WAIT_EVENT_0],NULL,NULL);
//当套接字的数量超界时,关闭该套接字
if(EventTotal>WSA_MAXIMUN_EVENTS)
{
printf("Too many connections");
closesocket(socketConn);
break;
}
NewEvent = WSACreateEvent();
// WSAEventSelect(socketConn,NewEvent,FD_READ|FD_WRITE);
if (SOCKET_ERROR == WSAEventSelect(socketConn,NewEvent,FD_READ|FD_WRITE|FD_CLOSE))
{
printf("WSAEventSelect() failed with error %d\n", WSAGetLastError());
// return;
}
EventArray[EventTotal] = NewEvent;
SocketArray[EventTotal] = socketConn;
EventTotal++;
//处理FD_READ通知
if(NetworkEvents.lNetworkEvents&FD_READ)
{
if(0 != NetworkEvents.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d\n",NetworkEvents.iErrorCode[FD_READ_BIT]);
break;
}
//从套接字读入数据
char recvBuf[MAX_BUF_LEN];
recv(SocketArray[Index-WSA_WAIT_EVENT_0],recvBuf,MAX_BUF_LEN,0);
printf("The receive buffer string is: %s\n",recvBuf);
}
//处理FD_WRITE通知
if(NetworkEvents.lNetworkEvents&FD_WRITE)
{
if(0 != NetworkEvents.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d\n",NetworkEvents.iErrorCode[FD_WRITE_BIT]);
break;
}
//从套接字写入数据
addrClient.sin_addr.S_un.S_addr = inet_addr("210.45.251.236");
char sendBuf[MAX_BUF_LEN];
sprintf(sendBuf,"The server say :Welcome to connect %s !",inet_ntoa(addrClient.sin_addr));
printf("The send buffer string is: %s\n",sendBuf);
//发送数据
send(SocketArray[Index-WSA_WAIT_EVENT_0],sendBuf,strlen(sendBuf)+1,0);
}
//处理FD_CLOSE通知
if(NetworkEvents.lNetworkEvents&FD_CLOSE)
{
if(0 != NetworkEvents.iErrorCode[FD_CLOSE_BIT])
{
printf("FD_CLOSE failed with error %d\n",NetworkEvents.iErrorCode[FD_CLOSE_BIT]);
break;
}
//关闭套接字
closesocket(SocketArray[Index-WSA_WAIT_EVENT_0]);
CompressArrays(Index-WSA_WAIT_EVENT_0,EventArray,SocketArray,&EventTotal);
}
}
WSACleanup();
}
void CompressArrays(int Index, WSAEVENT Event[WSA_MAXIMUM_WAIT_EVENTS],
SOCKET Socket[WSA_MAXIMUM_WAIT_EVENTS],
unsigned long *EventTotal)
{
//压缩数组,将Index后的数组项往前移以覆盖无效的项
for(int i=Index;i<WSA_MAXIMUM_WAIT_EVENTS;i++)
{
Event[i]=Event[i+1];
Socket[i]=Socket[i+1];
}
--(*EventTotal);
}