2024-03-19 作业

作业要求:

1> 将白天课堂代码重新实现一遍:

select实现的TCP并发服务器

poll实现的TCP客户端

2> 君子作业

select实现的TCP客户端

poll实现的TCP并发服务器

作业1:

运行代码:
select实现的TCP并发服务器
#include<myhead.h>
#define SER_IP "192.168.117.111"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字sfd
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==sfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:sfd = %d\n",sfd);
	//端口快速重用
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){
		perror("reuse error");
		return -1;
	}
	printf("reuse success\n");
	//2.绑定bind
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("bind error");
		return -1;
	}
	printf("bind success \n");
	//3.开启监听
	if(listen(sfd,128)==-1){
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	//4
	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);
	//堵塞文件设置select
	fd_set readfd,tempfd;
	FD_ZERO(&readfd);
	FD_SET(0,&readfd);//放入输入文件
	FD_SET(sfd,&readfd);//放入sfd
	int maxfd=sfd;
	int newfd;
	struct sockaddr_in cin_arr[1024];//存放客户端信息
	char sbuf[128]="";
	while(1){
		tempfd = readfd;
		int res = select(maxfd+1,&tempfd,NULL,NULL,NULL);//筛选tempfd
		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

	/********************************/	
		for(int i = 0;i<=maxfd;i++){
			//接受连接请求
			if(!(FD_ISSET(i,&tempfd))){
				continue;
			}	
			if(i==sfd){
				if(FD_ISSET(sfd,&tempfd)){
					if((newfd = accept(sfd,(struct sockaddr *)&cin,&socklen))==-1){
						perror("accept error");
						return -1;
					}
					printf("[%s %d]发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
					FD_SET(newfd,&readfd);//将newfd加入检测数组
					if(newfd>maxfd){
						maxfd = newfd;
					}
					cin_arr[newfd]=cin;//cin放入数组
				}
	/**********************************/
			}else if(i==0){
				//输入设置
				if(FD_ISSET(0,&tempfd)){
					bzero(sbuf,sizeof(sbuf));
					fgets(sbuf,sizeof(sbuf)-1,stdin);
					sbuf[strlen(sbuf)-1]=0;
					for(int j=4;j<=maxfd;j++){
						if(FD_ISSET(j,&readfd)){
							send(j,sbuf,strlen(sbuf),0);
							printf("发送成功\n");
						}
					}
				}
	/***********************************/
			}else if(i>3){
				//接受客户端信息
				if(FD_ISSET(i,&tempfd)){
					bzero(sbuf,sizeof(sbuf));
					int ret = recv(i,sbuf,sizeof(sbuf)-1,0);
					if(ret <=0){
						printf("对方已下线\n");
						//除去客户端的文件描述符
						FD_CLR(i,&readfd);
						close(i);
						if(i==maxfd){
							for(int j=maxfd-1;j>=3;j--){
								if(FD_ISSET(j,&readfd)){
									maxfd = j;
									break;
								}
							}//for
						}//if
						continue;
					}//if
					printf("[%s %d]>>>%s\n",inet_ntoa(cin_arr[i].sin_addr),htons(cin_arr[i].sin_port),sbuf);
					strcat(sbuf,"*<*");
					send(i,sbuf,strlen(sbuf),0);
				}//if
			}//i>3
	/************************************/
		}//for

}
	//关闭文件
	close(sfd);
	return 0;
}
 poll实现的TCP客户端
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字cfd
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==cfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:cfd = %d\n",cfd);
	//连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	
	//堵塞文件设置pfd
	struct pollfd pfd[2];
	 pfd[0].fd=0;
	 pfd[0].events=POLLIN;
	 pfd[1].fd=cfd;
	 pfd[1].events=POLLIN;
	char cbuf[128]="";
	//连接
	if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
	while(1){
		int res = poll(pfd,2,-1);

		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

		//输入设置
		if(pfd[0].revents==POLLIN){
			bzero(cbuf,sizeof(cbuf));
			fgets(cbuf,sizeof(cbuf)-1,stdin);
			cbuf[strlen(cbuf)-1]=0;
			send(cfd,cbuf,strlen(cbuf),0);
		}
		/***********************************/
		//接受客户端信息
		if(pfd[1].revents==POLLIN){
			bzero(cbuf,sizeof(cbuf));
			int ret = recv(cfd,cbuf,sizeof(cbuf),0);
			if(ret <= 0){
				printf("服务器已下线\n");
				return 0;
			}
			printf("服务器发来>>>%s\n",cbuf);
		}
	}
		//关闭文件
		close(cfd);
		return 0;
}
运行截图: 

作业2:

运行代码:
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字cfd
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==cfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:cfd = %d\n",cfd);
	//连接
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	
	//堵塞文件设置select
	fd_set readfd,tempfd;
	FD_ZERO(&readfd);
	FD_SET(0,&readfd);//放入输入文件
	FD_SET(cfd,&readfd);//放入cfd
	char cbuf[128]="";
	//连接
	if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
	while(1){
		tempfd = readfd;
		int res = select(cfd+1,&tempfd,NULL,NULL,NULL);//筛选tempfd
		if(res==0){
			continue;
		}else if(res = 0){
			perror("select error");
			return -1;
		}

		//输入设置
		if(FD_ISSET(0,&tempfd)){
			bzero(cbuf,sizeof(cbuf));
			fgets(cbuf,sizeof(cbuf)-1,stdin);
			cbuf[strlen(cbuf)-1]=0;
			send(cfd,cbuf,strlen(cbuf),0);
		}
		/***********************************/
		//接受客户端信息
		if(FD_ISSET(cfd,&tempfd)){
			bzero(cbuf,sizeof(cbuf));
			recv(cfd,cbuf,sizeof(cbuf),0);
			printf("服务器发来>>>%s\n",cbuf);
		}
	}
		//关闭文件
		close(cfd);
		return 0;
}
poll实现的TCP并发服务器 
#include<myhead.h>
#define SER_IP "192.168.1.101"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{
	//1.创建套接字sfd
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1==sfd){
		perror("socket error");
		return -1;
	}
	printf("socket success:sfd = %d\n",sfd);
	//端口快速重用
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){
		perror("reuse error");
		return -1;
	}
	printf("reuse success\n");
	//2.绑定bind
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
		perror("bind error");
		return -1;
	}
	printf("bind success \n");
	//3.开启监听
	if(listen(sfd,128)==-1){
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	//4
	struct sockaddr_in cin;
	socklen_t socklen = sizeof(cin);
	//堵塞文件设置poll
	struct pollfd pfd[1024];
	pfd[0].fd = 0;
	pfd[0].events=POLLIN;
	pfd[1].fd = sfd;
	pfd[1].events=POLLIN;
	int newfd;
	int num=2;
	struct sockaddr_in cin_arr[1024];//存放客户端信息
	char sbuf[128]="";
	while(1){
		//设置堵塞
		int res = poll(pfd,num,-1);
		if(res==0){
			continue;
		}else if(res == 0){
			perror("select error");
			return -1;
		}

		/********************************/	
		for(int i = 0;i<num;i++){
			//接受连接请求
			if(!(pfd[i].revents==POLLIN)){
				continue;
			}	
			if(i==1){
				if(pfd[i].revents==POLLIN){
					if((newfd = accept(sfd,(struct sockaddr *)&cin,&socklen))==-1){
						perror("accept error");
						return -1;
					}
					printf("[%s %d]发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
					pfd[num].fd=newfd;//将newfd加入检测数组
					pfd[num].events=POLLIN;

					cin_arr[newfd]=cin;//cin放入数组
					num++;
				}
				/**********************************/
			}else if(i==0){
				//输入设置
				if(pfd[0].revents==POLLIN){
					bzero(sbuf,sizeof(sbuf));
					fgets(sbuf,sizeof(sbuf)-1,stdin);
					sbuf[strlen(sbuf)-1]=0;
					for(int j=2;j<=num;j++){
						if(pfd[j].events==POLLIN){
							send(pfd[j].fd,sbuf,strlen(sbuf),0);
						}
					}
					printf("发送成功\n");
				}
				/***********************************/
			}else if(i>=2){
				//接受客户端信息
				if(pfd[i].revents==POLLIN){
					bzero(sbuf,sizeof(sbuf));
					int ret = recv(pfd[i].fd,sbuf,sizeof(sbuf)-1,0);
					if(ret <=0){
						printf("对方已下线\n");
						//除去客户端的文件描述符
						close(pfd[i].fd);
						if(i==num-1){
							num--;
						}else{
							pfd[i]=pfd[num-1];
							num--;
						}
						
						continue;
					}//if
					printf("[%s %d]>>>%s\n",inet_ntoa(cin_arr[pfd[i].fd].sin_addr),htons(cin_arr[pfd[i].fd].sin_port),sbuf);
					strcat(sbuf,"*<*");
					send(pfd[i].fd,sbuf,strlen(sbuf),0);
				}//if
			}//i>3
			/************************************/
		}//for

	}
	//关闭文件
	close(sfd);
	return 0;
}
运行截图: 

相关推荐

  1. 2022-04-10作业

    2024-03-21 11:12:03       18 阅读
  2. 2024.4.19作业

    2024-03-21 11:12:03       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-21 11:12:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-21 11:12:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-21 11:12:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-21 11:12:03       20 阅读

热门阅读

  1. C#关键字 sealed、unsafe、virtual、volatile

    2024-03-21 11:12:03       21 阅读
  2. ORA-00845: MEMORY_TARGET not supported on this system

    2024-03-21 11:12:03       19 阅读
  3. Spring Boot创建一个实例

    2024-03-21 11:12:03       19 阅读
  4. axios、axios二次封装、api解耦

    2024-03-21 11:12:03       17 阅读
  5. MFC 自定义分发消息方法

    2024-03-21 11:12:03       17 阅读
  6. 设计模式(行为型设计模式——迭代器模式)

    2024-03-21 11:12:03       18 阅读
  7. (六):分支和循环结构的应用

    2024-03-21 11:12:03       15 阅读
  8. C++ 设计模式:观察者模式

    2024-03-21 11:12:03       22 阅读
  9. C++设计模式之访问者模式

    2024-03-21 11:12:03       18 阅读
  10. Reactive: Vue3数据更新但是表单没有更新

    2024-03-21 11:12:03       22 阅读
  11. 在Spring Boot中如何处理跨域请求(CORS)?

    2024-03-21 11:12:03       21 阅读
  12. Elasticsearch8搭建及Springboot中集成使用

    2024-03-21 11:12:03       18 阅读