#include <iostream> using namespace std; #ifdef WINDOWS_SOCK #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define socklen_t int #else #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #define SOCKET int #define closesocket(a) close(a) #endif #define SOCK_COUNT 5 SOCKET initSock(); int main() { SOCKET skListen = initSock(); //select int maxfd = skListen; int conn_count = 0; SOCKET skAll[SOCK_COUNT] = {0}; char sndbuf[1024]; sndbuf[0] = ‘\0‘; fd_set fdsetr, fdsetw; FD_ZERO(&fdsetr); FD_ZERO(&fdsetw); FD_SET(skListen, &fdsetr); fd_set fdRead; fd_set fdWrite; sockaddr_in acceptAddr; socklen_t len = sizeof(acceptAddr); //该参数为空时,则为阻塞select了 struct timeval timeout = {3,0}; while(true) { fdRead = fdsetr; fdWrite = fdsetw; //参考unix网络编程卷1(第三版):第6章,每个参数介绍很详细 int num = select(maxfd + 1, &fdRead, &fdWrite, 0, &timeout); if (num > 0) { for (int i=0; i<conn_count; i++) { //recv if(FD_ISSET(skAll[i], &fdRead)) { char buf[1024]; int ir = recv(skAll[i], buf, 1024, 0); if (ir == -1) { getpeername(skAll[i], (sockaddr*)&acceptAddr, &len); cout<<"diss conn IP:"<<inet_ntoa(acceptAddr.sin_addr) <<",PORT:"<<ntohs(acceptAddr.sin_port)<<endl; closesocket(skAll[i]); FD_CLR(skAll[i], &fdsetr); skAll[i] = 0; conn_count--; } else if (ir == 0) { cout<<"0:disconnect"<<endl; closesocket(skAll[i]); FD_CLR(skAll[i], &fdsetr); skAll[i] = 0; conn_count--; } else { buf[ir]=‘\0‘; cout<<buf<<endl; //fdwrite char snd[50] = "notify client"; memcpy(sndbuf, snd, strlen(snd)+1); FD_SET(skAll[i], &fdsetw); } } //write if (FD_ISSET(skAll[i], &fdWrite)) { int ilen = strlen(sndbuf); if (ilen > 0) { int ret = send(skAll[i], sndbuf, ilen, 0); if (ret > 0 ) { cout<<"send :"<<ret<<endl; } //FD_CLR(skAll[i], &fdsetr); //FD_CLR(skAll[i], &fdsetw); //closesocket(skAll[i]); //conn_count--; } sndbuf[0] = ‘\0‘; } }//end for //accept if (FD_ISSET(skListen, &fdRead)) { SOCKET skClient = accept(skListen, (sockaddr*)&acceptAddr, &len); cout<<"conn IP:"<<inet_ntoa(acceptAddr.sin_addr) <<",PORT:"<<ntohs(acceptAddr.sin_port)<<endl; FD_SET(skClient, &fdsetr); maxfd = skListen > skClient ? skListen : skClient; if (conn_count >= SOCK_COUNT) { cout<<"max conn limit"<<endl; closesocket(skClient); } else { int tmp = conn_count; do { if(skAll[tmp] == 0) { skAll[conn_count++] = skClient; break; } tmp++; if (tmp== SOCK_COUNT) { tmp= 0; } }while(conn_count != tmp); } } } } system("pause"); return 0; } SOCKET initSock() { #ifdef WINDOWS_SOCK //1.init WSADATA wsa; if (WSAStartup(MAKEWORD(2,2), &wsa)) { cout<<"1"<<endl; } #endif //2.socket SOCKET skListen = socket(AF_INET, SOCK_STREAM, 0); //3.bind sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = htonl(INADDR_ANY); bind(skListen, (sockaddr*)&addr, sizeof(addr)); //4.listen listen(skListen, 5); return skListen; }
时间: 2024-11-05 18:33:41