8080,8989端口可以连接多个客户端,然后在本地创建连接套接字,用select监听这些套接字的读写,同时select也监听着来自绑定了8080和8989两个端口的监听套接字,当有连接来了可以处理,用set维护着已连接套接字。
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <algorithm>
#include <poll.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <errno.h>
#include <set>
#include <vector>
using namespace std;
const char* str = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n <html>hello web server<html/>";
// 创建监听套接字
int create_listen_fd(int port) {
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr));
listen(listenfd,5);
return listenfd;
}
// 创建两个套接字并同时接收其输入
int main(){
socklen_t len;
struct sockaddr_in cliaddr;
// 获得两个端口的监听套接字,用select监听这两个套接字
int fd1 = create_listen_fd(8989);
int fd2 = create_listen_fd(8080);
// printf("%d %d\n", fd1, fd2); // 3,4
fd_set allset, rs;
FD_ZERO(&allset);
FD_SET(fd1,&allset);
FD_SET(fd2, &allset);
char buf[100000];
set<int> cliset; // 存放已连接套接字的集合
int maxfd = max(fd2,fd1);
for(;;) {
rs = allset;
if (select(maxfd + 1, &rs, NULL,NULL , NULL) < 0) { //阻塞直到有一个可读
printf("err for select\n");
}
if (FD_ISSET(fd1,&rs)) {
len = sizeof(cliaddr);
int connfd =accept(fd1, (struct sockaddr*)&cliaddr, &len);
printf("通过8989端口连接到%s\n", inet_ntoa(cliaddr.sin_addr));
printf("新创建文件描述符:%d\n", connfd);
FD_SET(connfd,&allset);
maxfd = max(maxfd, connfd);
cliset.insert(connfd);
}
if (FD_ISSET(fd2,&rs)) {
len = sizeof(cliaddr);
int connfd =accept(fd2, (struct sockaddr*)&cliaddr, &len);
printf("通过8080端口连接到%s\n", inet_ntoa(cliaddr.sin_addr));
printf("新创建文件描述符:%d\n", connfd);
FD_SET(connfd,&allset);
maxfd = max(maxfd, connfd);
cliset.insert(connfd);
}
vector<int> need_del;
for (auto & it : cliset) {
if(FD_ISSET(it, &rs)) {
int n;
if((n = read(it, buf, sizeof(buf))) < 0) {
printf("err");
} else if (n == 0) {
close(it);
need_del.push_back(it);
FD_CLR(it,&allset);
printf("已经关闭连接-%d\n",it);
} else {
buf[n-1] = '\0';
printf("%s\n", buf);
}
printf("返回一些数据\n");
printf("%s\n",str);
write(it,str,strlen(str));
}
}
for(auto & it : need_del) {
cliset.erase(it);
}
}
exit(0);
}