// SelectServer.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <conio.h>
#pragma comment(lib,"ws2_32")
#define SOCKET_MAXCNT 64
#define THREAD_NUM 2
#define CONNECT_PORT 8773
#define CONNECT_ADDR "127.0.0.1"
#define DATA_BUF_SZIE 8192
typedef struct
_SOCKET_INFORMATION {
CHAR Buffer[DATA_BUF_SZIE];
WSABUF DataBuf;
SOCKET Socket;
OVERLAPPED Overlapped;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
DWORD totalSockets = 0;
LPSOCKET_INFORMATION SocketArray[FD_SETSIZE];
BOOL CreateSocketInformation(SOCKET s)
{
LPSOCKET_INFORMATION SI;
printf( "Accepted socket number %d\n" , s);
if
((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof (SOCKET_INFORMATION))) == NULL)
{
printf( "GlobalAlloc() failed with error %d\n" , GetLastError());
return
FALSE;
}
// Prepare SocketInfo structure for use.
SI->Socket = s;
SocketArray[totalSockets] = SI;
totalSockets++;
return (TRUE);
}
void
FreeSocketInformation(DWORD Index)
{
LPSOCKET_INFORMATION SI = SocketArray[Index];
DWORD i;
closesocket(SI->Socket);
printf( "Closing socket number %d\n" , SI->Socket);
GlobalFree(SI);
// Squash the socket array
for
(i = Index; i < totalSockets; i++)
{
SocketArray[i] = SocketArray[i + 1];
}
totalSockets--;
}
int
_tmain( int
argc, _TCHAR* argv[])
{
WSAData wsaData;
SOCKADDR_IN InternetAddr = {0};
FD_SET ReadSet;
DWORD i = 0;
DWORD total = 0;
DWORD Flags;
DWORD RecvBytes = 0;
SOCKET listenSock = INVALID_SOCKET;
SOCKET acceptSock = INVALID_SOCKET;
if ( WSAStartup(MAKEWORD(2,2),&wsaData) != 0 )
{
printf( "WSAStartup error,exit\n" );
goto
SOCKET_CLEAN;
}
listenSock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
WSA_FLAG_OVERLAPPED);
if (listenSock == INVALID_SOCKET)
{
printf( "WSASocket error \n" );
goto
SOCKET_CLEAN;
}
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(CONNECT_PORT);
if
(bind(listenSock, (PSOCKADDR) &InternetAddr, sizeof (InternetAddr))
== SOCKET_ERROR)
{
printf( "bind() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
if
(listen(listenSock, 5))
{
printf( "listen() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
// Change the socket mode on the listening socket from blocking to
// non-block so the application will not block waiting for requests.
ULONG NonBlock = 1;
if
(ioctlsocket(listenSock, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
printf( "ioctlsocket() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
while (1)
{
FD_ZERO(&ReadSet);
FD_SET(listenSock, &ReadSet);
for
(i = 0; i < totalSockets; i++)
{
FD_SET(SocketArray[i]->Socket, &ReadSet);
}
total = select (0,&ReadSet,NULL,NULL,NULL);
if (total == SOCKET_ERROR)
{
printf( "select() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
if (FD_ISSET(listenSock,&ReadSet))
{
total--;
acceptSock = accept(listenSock,NULL,NULL);
if (acceptSock == INVALID_SOCKET)
{
if
(WSAGetLastError() != WSAEWOULDBLOCK)
{
printf( "accept() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
} else
{
NonBlock = 1;
int
ret = ioctlsocket(acceptSock,FIONBIO, &NonBlock);
if (ret == SOCKET_ERROR)
{
printf( "ioctlsocket() failed with error %d\n" , WSAGetLastError());
goto
SOCKET_CLEAN;
}
if
(CreateSocketInformation(acceptSock) == FALSE)
goto
SOCKET_CLEAN;
}
}
for
(i = 0; total > 0 && i < totalSockets; i++)
{
LPSOCKET_INFORMATION SocketInfo = SocketArray[i];
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
SocketInfo->DataBuf.len = DATA_BUF_SZIE;
if (FD_ISSET(SocketInfo->Socket,&ReadSet))
{
total--;
Flags = 0;
ZeroMemory(SocketInfo->Buffer,DATA_BUF_SZIE);
if
(WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
&Flags, NULL, NULL) == SOCKET_ERROR)
{
if
(WSAGetLastError() != WSAEWOULDBLOCK)
{
printf( "WSARecv() failed with error %d\n" , WSAGetLastError());
FreeSocketInformation(i);
}
continue ;
} else
{
printf(SocketInfo->Buffer);
if (RecvBytes == 0)
{
FreeSocketInformation(i);
continue ;
}
}
}
}
}
SOCKET_CLEAN:
if (listenSock != INVALID_SOCKET)
{
closesocket(listenSock);
listenSock = INVALID_SOCKET;
}
if (acceptSock != INVALID_SOCKET)
{
closesocket(acceptSock);
acceptSock = INVALID_SOCKET;
}
WSACleanup();
return
0;
}
|