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;
}