The selection model is the simplest one in the I/O model. The server side adds and removes pending IO socket handles through events in the loop by creating two sockets collection Fdold and Fdnew. When testing, start the server and then start the client.
The following is the server-side source code (tested under VS2010):
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
using namespace Std;
BOOL Initsocket ();
BOOL SelectMode ();
int _tmain (int argc, _tchar* argv[])
{
if (Initsocket () ==false)
{
return 0;
}
if (SelectMode () ==false)
{
}
WSACleanup;
return 0;
}
BOOL Initsocket ()
{
Wsadata wsadata={0};
if (WSAStartup (Makeword (2,2), &wsadata) ==0)
{
return TRUE;
}
return FALSE;
}
BOOL SelectMode ()
{
Creating a listening socket
SOCKET Slistensocket;
Slistensocket=socket (af_inet,sock_stream,0);
if (Slistensocket==invalid_socket)
{
return FALSE;
}
Sockaddr_in serveraddr;
Serveraddr.sin_family=af_inet;
Serveraddr.sin_port=htons (2356);
Serveraddr.sin_addr. S_un. S_addr=inaddr_any;
int Iresult=bind (Slistensocket, (sockaddr*) &serveraddr,sizeof (SERVERADDR));
if (iresult==socket_error)
{
return FALSE;
}
Listen (slistensocket,5);
Create a Socket collection
Fd_set Fdold;
Fd_set fdnew;
Initialize Socket collection
fdold.fd_count=0;
fdnew.fd_count=0;
Put the listener socket in the Fdold collection
Fd_set (Slistensocket,&fdold);
while (true)
{
Passes a copy of the Fdold collection fdnew to the Select function
When an event occurs, the Select function removes a socket handle with no pending I/O operations in the Fdnew collection, and then returns
Fdnew=fdold;
int Ireturn=select (0,&fdnew,null,null,null);//The first parameter is ignored, the second parameter points to a socket collection, checks its readability, and the third parameter points to a socket collection to check its writable properties
The fourth parameter points to a socket collection, checks for errors, and the fifth parameter specifies the maximum time this function waits, or infinitely long if NULL
int i=0;
for (i=0;i<fdold.fd_count;i++)
{
if (Fd_isset (fdold.fd_array[i],&fdnew)!=0)//Determine which sockets have pending I/O
{
if (fdold.fd_array[i]==slistensocket)//If the socket is a listening socket
{
Define a communication socket
SOCKET Sclientsocket;
Sockaddr_in clientaddr;
int addrlen=sizeof (CLIENTADDR);
Sclientsocket=accept (Slistensocket, (sockaddr*) &serveraddr,&addrlen);
if (Sclientsocket==invalid_socket)
{
Continue
}
Put the communication socket into the Fdold
if (fdold.fd_count<fd_setsize)
{
Fd_set (Sclientsocket,&fdold);
}
Else
{
Send (Sclientsocket, "Waiting", strlen ("Waiting"), 0);
Closesocket (Sclientsocket);
}
Continue
}
else//If the socket is a communication socket
{
Char szbuffer[0x1000]={0};
int Ilength=recv (fdold.fd_array[i],szbuffer,0x1000,0);
if (ilength<0)//return value less than 0 indicates that the client is closed, the corresponding communication socket in the Fdold set is closed
{
Closesocket (Fdold.fd_array[i]);
FD_CLR (Fdold.fd_array[i],&fdold);
cout<< "one Client Lost" <<endl;
Continue
}
szbuffer[ilength]= ' + ';
cout<<szbuffer<<endl;
}
}
}
}
}
The following is the client source code:
#include "stdafx.h"
#include <WinSock2.h>//This header file must be put in front, in Ws2_32.dll
#include <Windows.h>//in Kernel32.dll
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")//Load Static library
using namespace Std;
SOCKET Sclientsocket;
BOOL Initsocket ();//boot socket font
DWORD WINAPI recvthread ();//Declaration handle
int _tmain (int argc, _tchar* argv[])
{
cout<< "Client" <<endl;
if (Initsocket () ==false)//initialization failed
{
cout<< "Init Socket Error" <<endl;
return 0;
}
Communication sockets
Sclientsocket = socket (af_inet,sock_stream,0);
if (Sclientsocket==invalid_socket)
{
cout<< "Create Listen Socket error\r\n";
WSACleanup ();
Return 0;
}
//Initialize the NIC
sockaddr_in serveraddr;
serveraddr.sin_family=af_inet;//indicates the protocol family
Serveraddr.sin_addr. S_un. S_ADDR=INET_ADDR ("192.168.1.113");//instructs IP,INET_ADDR to convert the IP address into a form that the computer can understand
Serveraddr.sin_port=htons (2356);//Port, Indicates that the packet is accepted at the appropriate port on the application tier, which is to send the data and accept the data to use the same port, if not on the WAN, you can indicate the
Connection
int Iret=connect (Sclientsocket, (sockaddr*) &serveraddr,sizeof (SERVERADDR));
if (iret==socket_error)
{
cout<< "fail to connect";
}
HANDLE hthread =createthread (null,0, (lpthread_start_routine) recvthread,null,0,null);//start handle
if (iret==socket_error)//If the binding fails, free memory
{
cout<< "Connect Error" <<endl;
Closesocket (Sclientsocket);
WSACleanup ();
return 0;
}
Receive data
Char szbuffer[0x1000]={0};
while (true)//dead loop, let communication sockets continue to work
{
cin>>szbuffer;
Send (Sclientsocket,szbuffer,strlen (szbuffer), 0);//Sending data
}
WaitForSingleObject (Hthread,infinite);
WSACleanup ();//unbind the socket library and release the resources that the socket library consumes
return 0;
}
DWORD WINAPI Recvthread ()
{
while (true)
{
Char szbuffer[0x1000]={0};
DWORD dwreturn=recv (sclientsocket,szbuffer,0x1000,0);//Receive Data
if (dwreturn<=0)
{
Break
}
Szbuffer[dwreturn]= ';//Remember to add the
cout<<szbuffer<<endl;
}
return 0;
}
BOOL Initsocket ()
{
WORD v1 = 0;
V1 = Makeword (2,2);//indicates Winsock2.2 version
Wsadata Wsadata = {0};
if ((WSAStartup (V1,&wsadata) ==0))//Initialize Winsock DLL
{
return TRUE;
}
return FALSE;
}
Windows network Programming-Choose (SELECT) model