select 服务器客户端 poll客户端 基于tcp的ftp服务器

select服务器

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h> 
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/select.h>


void select_test(){
	//创建套接字
	
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0){
		perror("socket");
		return;
	}


	//绑定
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8888);
	addr.sin_addr.s_addr=inet_addr("192.168.8.207");
	bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));

	//监听
	listen(sockfd,128);

	char buf_select[20]="";
	char buf_rec[20]="";
	struct sockaddr_in record[1021];
	struct sockaddr_in raddr;
	//创建读集合
	fd_set readfds;
	fd_set tempfds;
	//初始化集合
	FD_ZERO(&readfds);
	FD_ZERO(&tempfds);

	//将文件描述符添加到集合
	FD_SET(0,&readfds);
	FD_SET(sockfd,&tempfds);

	//设置最大文件描述符
	int maxfd=sockfd;

	int opt;
	int len=sizeof(raddr);
	int accfd;
	while(1){
		tempfds=readfds;
		int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);
		if(res<0){
			perror("select");
			return ;
		}
		
		for(int i=0;i<maxfd;i++){
			if(FD_ISSET(i,&tempfds)==0){
				continue;
			}

			if(i==0){
				

				printf("发送信息格式:文件描述符 信息\n");
				scanf("%d %s\n",&opt,buf_select);			
				send(opt,buf_select,sizeof(buf_select),0);


			}else if(i==sockfd){
			//连接
			accfd=accept(sockfd,(struct sockaddr*)&raddr,&len);
			if(accfd<0){
				perror("accpet");
				return ;
			}
			
			FD_SET(accfd,&readfds);
			if(accfd>maxfd){
				maxfd=accfd;
			}

			}else{
				int res=recv(i,buf_rec,sizeof(buf_rec),0);
				if(res==0){
				printf("客户端断开连接\n");	   //客户端断开连接
				//将accfd从readfds中删除
				FD_CLR(i,&readfds);
				//重置maxfd
				for(int j=maxfd;j>0;j--){
					maxfd=j;
					break;
				}
				}else if(res<0){
					perror("recv");
					return;
				}
				
				printf("[%d]accfd=%d---buf_rec=%s\n",ntohs(record[i].sin_port),i,buf_rec);

			}



		}

	
	}

	close(accfd);
	close(sockfd);


}

int main(){
	select_test();
	return 0;
}

selec 客户端

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h> 
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <linux/input.h>
void select_test(){
	//创建套接字
	
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0){
		perror("socket");
		return;
	}


	char buf_select[20]="";
	char buf_rec[20]="";
	struct sockaddr_in record[1021];
	struct sockaddr_in raddr;

	//填充服务器信息
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8888);
	addr.sin_addr.s_addr=inet_addr("192.168.8.207");
	connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
	

	//创建读集合
	fd_set readfds;
	fd_set tempfds;
	//初始化集合
	FD_ZERO(&readfds);
	FD_ZERO(&tempfds);

	//将文件描述符添加到集合
	FD_SET(0,&readfds);
	FD_SET(sockfd,&tempfds);

	//设置最大文件描述符
	int maxfd=sockfd;

	int opt;
	int len=sizeof(raddr);
	while(1){
		tempfds=readfds;
		int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);
		if(res<0){
			perror("select");
			return ;
		}
		
		for(int i=0;i<maxfd;i++){
			if(FD_ISSET(i ,&tempfds) == 0)
			{
				continue;
			}

			if(i==0){
				
				printf("发送信息\n");
				scanf("%s\n",buf_select);			
				send(i,buf_select,sizeof(buf_select),0);


			}else if(i==sockfd){
				int res=recv(sockfd,buf_rec,sizeof(buf_rec),0);
				if(res<0){
					perror("recv");
					return ;
				}
				printf("%s\n",buf_rec);
			}
			

		}
	
	}


}




int main(){
	select_test();
	return 0;
}

poll客户端

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h> 
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <linux/input.h>
#include <poll.h>

void poll_test(){
	//创建套接字
	
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0){
		perror("socket");
		return;
	}

	//填充服务器信息
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_port=htons(8888);
	addr.sin_addr.s_addr=inet_addr("192.168.8.207");
	connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));

	struct pollfd fds[2];
	fds[0].fd=0;
	fds[0].events=POLLIN;

	fds[1].fd=sockfd;
	fds[1].events=POLLIN;
	
	char buf_snd[20]="";
	char buf_rec[20]="";
	while(1){
		poll(fds,2,-1);

		if(fds[0].revents&POLLIN){
			scanf("%s",buf_snd);
			while(getchar()!=10);
			send(sockfd,buf_snd,sizeof(buf_snd),0);
		}

		if(fds[1].revents&POLLIN){
			int res=recv(sockfd,buf_rec,sizeof(buf_rec),0);
			if(res<0){
				perror("recv");
				return ;
			}
			if(res==0){
				printf("服务器断开");
				break;
			}
			
			printf("%s\n",buf_rec);

			
		}
	
	}


	close(sockfd);


}


int main(){
	poll_test();
	return 0;
}

基于tcp的ftp服务器

服务器

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h> 
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>

typedef struct{
	int accfd;
	struct sockaddr_in rec;
}trans_data; 

typedef struct{
	char buf_name[256];
	int count;
}listname;

void show_list(int accfd){
	listname name[20];
	memset(name,0,sizeof(name));
	
	
	int count=0;                   //目录中文件个数
	DIR* dir=opendir("./");
	if(dir==NULL){
		perror("opendir");
		return ;
	}
	struct dirent *res;
	while((res=readdir(dir))!=NULL){
		if(res->d_name[0]=='.'){         //去除隐藏文件
			continue;
		}
		strcpy(name[count].buf_name,res->d_name);
		count++;
	}
	name[0].count=count;     //结构体数组第一位中记录一共有多少文件
	send(accfd,name,sizeof(name),0);
	closedir(dir);
}

void download(int accfd,char *filename){          //对端上传

	char buf_rec[256]="";

	int fd=open(filename,O_WRONLY|O_CREAT,0777);//获取文件名,先创建
	if(fd<0){
		perror("open");
		send(accfd,"operate error",13,0);
		return ;
	}else if(fd >0){			
		send(accfd,"3",1,0);
	}

	char buf[20]="";
	while(1){
		bzero(buf,sizeof(buf));
		int res=recv(accfd,buf,sizeof(buf),0);
		write(fd,buf,res);
		if(res<20){
			break;
		}

	}
	close(fd);
	close(accfd);
}


void upload(int accfd,char* filename){  //对端下载
	
	char buf_rec[256]="";

	int fd=open(filename,O_RDONLY);//获取文件名,先创建
	if(fd<0){
		perror("open");
		send(accfd,"operate error",13,0);
		return ;
	}else if(fd >0){			
		send(accfd,"2",1,0);
	}

	while(1){
		bzero(buf_rec,sizeof(buf_rec));
		int res=read(fd,buf_rec,sizeof(buf_rec));
		send(accfd,buf_rec,res,0);
		if(res<256){
			break;
		}
		close(fd);
		close(accfd);
	}
}

// [flag+data]---flag=1 列表  flag=2---下载 flag=3---上传  
//  buf_recv[0]=1-----         2--------     3--------
//协议   [flag][filename][data]        flag--1byte  

void* callback(void* arg){    //服务线程
	
	int accfd=((trans_data*)arg)->accfd;
	struct sockaddr_in rec=((trans_data*)arg)->rec;
	
	char buf_recv[256];
	char filename[64];
	bzero(filename,sizeof(filename));
	bzero(buf_recv,sizeof(buf_recv));
	char *pflag=buf_recv;                 //flag
	char *pfilename=buf_recv+1;           //filename      

	while(1){
		recv(accfd,buf_recv,sizeof(buf_recv),0);  //获取需要操作的文件名 
		strcpy(filename,pfilename);
		char flag=buf_recv[0];
		if(flag=='1'){           //列表
			show_list(accfd);
			continue;
		}    
		if(flag=='2'){           //上传
			upload(accfd,filename);
			continue;
		}    
		if(flag=='3'){           //下载
			download(accfd,filename);
			continue;
		}
		if(flag==4){
			close(accfd);
			pthread_exit(0);
		}
	}
		


}



int main(){
	//创建套接字
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0){
		perror("socket");
		return 0;
	}

	struct sockaddr_in dest;
	dest.sin_family=AF_INET;
	dest.sin_port=htons(8888);
	dest.sin_addr.s_addr=inet_addr("192.168.8.207");
	//绑定
	bind(sockfd,(struct sockaddr*)&dest,sizeof(dest));

	//监听
	listen(sockfd,128);
	
	int len;
	while(1){
		//接收
		struct sockaddr_in rec;  //接收客户端信息
		len =sizeof(rec);	
		int accfd=accept(sockfd,(struct sockaddr*)&rec,&len);
		if(accfd<0){
			perror("accept");
			return 0;
		}

		trans_data data;
		data.accfd=accfd;
		data.rec=rec;
		pthread_t tid;
		pthread_create(&tid,NULL,callback,(void*)&data);
		pthread_detach(tid);
		
		
	}

	close(sockfd);
	return 0;

}

ftp客户端

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h> 
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <linux/input.h>
#include <stdlib.h>
#include <dirent.h>

//   [flag][filename][data]
typedef struct{
	char buf_name[256];
	int count;
}listname;

void show_list(int sockfd){
	listname name[20];
	char buf_list[256]="";	
	//组请求(列表)
	buf_list[0]='1';
	if(send(sockfd,buf_list,sizeof(buf_list),0)<0){
		perror("send");
		return;
	}
	//接收目录
	int res=recv(sockfd,name,sizeof(name),0);
	int num=name[0].count;
	for(int i=0;i<num;i++){
		printf("%s\n",name[i].buf_name);
	}
}


void download(int sockfd){
	char filename[20]="";
	printf("请输入要下载的文件名:\n");
	scanf("%s",filename);
	while(getchar()!=10);


	char buf_snd[256]="";

	//flag=2  + filename   组请求
	buf_snd[0]='2';
	char *pfilename=buf_snd+1;
	strcpy(pfilename,filename);
	send(sockfd,buf_snd,sizeof(buf_snd),0);
	bzero(buf_snd,sizeof(buf_snd));
	recv(sockfd,buf_snd,sizeof(buf_snd),0);
	if(buf_snd[0]!='2'){
		printf("%s",buf_snd);
	}
	int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0777);     //本地下载位置
	if(fd<0){
		perror("open");
		return ;
	}

	int res;                 //recv返回读取数
	char buf_rec[20]="";
	while(1){
		bzero(buf_rec,sizeof(buf_rec));
		int res=recv(sockfd,buf_rec,sizeof(buf_rec),0);
		write(fd,buf_rec,res);
		if(res<sizeof(buf_rec)){
			break;
		}

	}
	printf("下载完成\n");	
	close(fd);

	
}


void upload(int sockfd){
	char filename[20]="";
	printf("请输入要上传的文件名:\n");
	scanf("%s",filename);
	while(getchar()!=10);


	char buf_snd[256]="";

	//flag=2  + filename   组请求
	buf_snd[0]='3';
	char *pfilename=buf_snd+1;
	strcpy(pfilename,filename);
	send(sockfd,buf_snd,sizeof(buf_snd),0);
	bzero(buf_snd,sizeof(buf_snd));
	recv(sockfd,buf_snd,sizeof(buf_snd),0);
	if(buf_snd[0]!='3'){
		printf("%s",buf_snd);
	}

	int fd=open(filename,O_RDONLY);  
	if(fd<0){
		perror("open");
		return ;
	}
	char buf_rec[20]="";
	while(1){
		bzero(buf_rec,sizeof(buf_rec));
		int res=read(fd,buf_rec,sizeof(buf_rec));
		send(sockfd,buf_rec,res,0);
		if(res<20){
			break;
		}
	}
		printf("上传完成\n");
		close(fd);

}


int main(){
	//创建套接字
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0){
		perror("socket");
		return 0;
	}
	//连接
	struct sockaddr_in dest;
	dest.sin_family=AF_INET;
	dest.sin_port=htons(8888);
	dest.sin_addr.s_addr=inet_addr("192.168.8.207");
	connect(sockfd,(struct sockaddr*)&dest,sizeof(dest));

	char opt;
	while(1){
		system("clear");
		printf("请输入要操作的选项(1-列表 2-下载 3-上传 4-退出):\n");
		opt=getchar();
		while(getchar()!=10);
		switch(opt){
			case '1':
				show_list(sockfd);
				break;
			case '2':
				download(sockfd);
				break;
			case '3':
				upload(sockfd);
				break;
			case '4':
				printf("已退出\n");
				close(sockfd);
				exit(0);
				break;
			default:
				break;
		
		}
		printf("请按回车键继续\n");
		while(getchar()!=10);
	}
		
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值