#include <stdio.h>
#include <iostream>
#include <winsock2.h>
using namespace std;
int main(){
WORD version = MAKEWORD(2,2);
WSADATA wsaData;
SOCKET listenSocket;
SOCKET acceptSocket;
SOCKET clientSocket[FD_SETSIZE];
int static index = 0;
DWORD block = 1L;
FD_SET ReadSet;
//加载SOCKET库
int f = WSAStartup(version,&wsaData);
if (f != 0){
cout<<"加载Winsock 库错误! 错误号:"<<WSAGetLastError()<<endl;
return -1;
}
//创建监听SOCKET
listenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if (listenSocket == INVALID_SOCKET){
WSACleanup();
cout<<"创建监听SOCKET失败! 错误号:"<<WSAGetLastError()<<endl;
return -1;
}
cout<<"监听SOCKET创建成功!\n"<<endl;
//构造服务器地址
SOCKADDR_IN serverIp;
serverIp.sin_family = AF_INET;
serverIp.sin_port = htons(8108);
serverIp.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (bind(listenSocket,(SOCKADDR*)&serverIp,sizeof(SOCKADDR)) == SOCKET_ERROR){
cout<<"绑定服务器错误! 错误号:"<<WSAGetLastError()<<endl;
return -1;
}
cout<<"绑定操作成功!\n"<<endl;
if (listen(listenSocket,10) == SOCKET_ERROR){
cout<<"进入监听模式错误! 错误号:"<<WSAGetLastError()<<endl;
return -1;
}
cout<<"服务器已进入监听模式!\n"<<endl;
if (ioctlsocket(listenSocket,FIONBIO,&block) == SOCKET_ERROR){
Cout<<"监听SOCKET设置为非阻塞模式错误! 错误号:"<<WSAGetLastError()<<endl;
return -1;
}
cout<<"监听SOCKET已设置为非阻塞模式!\n\n\n"<<endl;
//非阻塞模式接受客户端连接
while(TRUE){
cout<<"持续按非阻塞模式接受客户端连接请求!\n\n"<<endl;
//将读SET 清0
FD_ZERO(&ReadSet);
//将已有客户端连接放到集合中!
for (int i = 0; i < index; i ){
cout<<"将clientSocket["<<i<<"]放到ReadSet集合中!\n"<<endl;
FD_SET(clientSocket[i],&ReadSet);
}
cout<<"监听SOCKET 放入 ReadSet集合中!\n\n"<<endl;
FD_SET(listenSocket,&ReadSet);
if (select(0,&ReadSet,NULL,NULL,NULL) == SOCKET_ERROR
cout<<"select 监听SOCET错误! 错误号:"<<WSAGetLastError()<<endl;
system("pause");
return -1;
}
cout<<"select 返回 说明已有客户端进行连接或有客户端数据读取或有客户端连接断开!\n\n\n"<<endl;
if (FD_ISSET(listenSocket,&ReadSet)){
cout<<"当前ReadSet中存监听SOCKET!\n\n"<<endl;
acceptSocket = accept(listenSocket,NULL,NULL);
if (acceptSocket != INVALID_SOCKET){
cout<<"客户端建立连接成功并保存到clientSocket["<<index<<"]中!\n\n"<<endl;
clientSocket[index] = acceptSocket;
index++ ;
}else {
cout<<"接收客户端连接错误! 错误号:"<<WSAGetLastError()<<endl;
continue;
}
}
for (int j = 0; j < index; j ){
if (FD_ISSET(clientSocket[j],&ReadSet)){
cout<<"当前ReadSet集合中有客户端SOCKET clientSocket["<<j<<"]可读数据!\n [message]"
char buffer[100]; memset(buffer,0,100);
if (recv(clientSocket[j],buffer,100,0) != SOCKET_ERROR){
cout<<buffer<<"[/messsage]\n"<<endl;
}else {
cout<<"客户端clientSocket["<<j<<"]出现错误! 错误号:"<<WSAGetLastError()<<endl;
clientSocket[j] = NULL;
index --;
closesocket(clientSocket[j])
break;
}
} }
}
}
下面这段代码与上面所述的While(True)部分基本一致,但我本人感觉下面的方法更好.
while(true)
{
fd_set fdRead=fdSocket;
if (::select(0,&fdSocket,NULL,NULL,NULL)==SOCKET_ERROR)
{
continue;
}
else
{
TRACE("Wait somebody % i\n ",fdSocket.fd_count);
for(int i=0;i<(int)fdSocket.fd_count;i++)
{
if(FD_ISSET( fdSocket.fd_array[i], &fdSocket))
{
if(fdSocket.fd_array[i]==sListen)
{
CString strIP;
sockaddr_in addrRemote;
int nAddrLen=sizeof(addrRemote);
SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
FD_SET(sNew,&fdSocket);
strIP.Format( "%s",inet_ntoa(addrRemote.sin_addr) );
TRACE("NEW COME %s\n",strIP);
}//end if ==slisten
else
{
int nRecev=::recv(fdSocket.fd_array[i],(char*)&recvPacket,sizeof(recvPacket),0);
if (nRecev>0)
{
TRACE("recv msg %s\n",recvPacket);
}else
{
::closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],&fdSocket);
}
}
}
}
}
}
return 0;