Socket网络编程: 应用
ftp服务器
客户端
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<sys/types.h> #include<unistd.h> #include<time.h> #define BUFLEN 1024 char *SERVERIP="127.0.0.1"; int SERVER_PORT=23336; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【多进程版·ftpclient:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char **argv) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); int tsock; tsock=socket(AF_INET,SOCK_STREAM,0); if(tsock<0) { printf("Create Socket Failed! \n"); exit(-1); } struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port=htons(SERVER_PORT); int ret; ret=connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); if(ret<0) { printf("Connect Failed!\n"); exit(-1); } char buf[BUFLEN]; memset(buf,'\0',sizeof(buf)); //接受服务器的文件名 if(recv(tsock,buf,sizeof(buf),0)>0) { printf("ftpclient>>\n"); printf("***************ftp_server当前目录文件***************\n"); puts(buf);//将结果显示在屏幕上 printf("*****************1.上传文件 2.下载文件*************\n"); } else { puts("ftpclient>>\n接受文件失败!\n"); exit(-1); } memset(buf, '\0',sizeof(buf)); printf("ftpclient>>"); scanf("%s",buf); //向服务器发送选择 if(send(tsock,buf,strlen(buf),0)<0) { puts("ftpclient>>发送数据失败!"); exit(-1); } if(strcmp(buf,"1")==0) { //上传文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("ftpclient>>"); scanf("%s",file_name); int len_file=strlen(file_name); file_name[len_file+1]='\0'; if(send(tsock,file_name,len_file+1,0)<0) { puts("ftpclient>>发送文件名失败!"); exit(-1); } FILE * fp=fopen(file_name,"r"); printf("%s\n",file_name); if(fp==NULL) { printf("ftpclient>>文件%s不存在\n",file_name); } else { char buffer[my_BUFSIZ]; memset(buffer,'\0',my_BUFSIZ); int file_block_length=0; while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0) { // printf("ftpserver>>文件块大小:%d\n",file_block_length); if(send(tsock,buffer,file_block_length,0)<0) { printf("ftpclient>>文件%s发送失败\n",file_name); break; exit(-1); } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("ftpclient>>文件%s发送成功\n",file_name); } } else if(strcmp(buf,"2")==0) { //下载文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("ftpclient>>"); scanf("%s",file_name); //向服务器发送buffer中的数据,buffer中放的是文件的名字 if(send(tsock,file_name,strlen(file_name),0)<0) { printf("ftpclient>>发送数据失败!\n"); exit(-1); } //接受文件 FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("ftpclient>>文件%s不可打开\n",file_name); exit(-1); } char buffer[my_BUFSIZ]; memset(buffer,'\0',my_BUFSIZ); int num; while(num=recv(tsock,buffer,my_BUFSIZ,0)) { // printf("ftpclient>>接收文件长度:%d\n",num); if(num < 0) { printf("ftpclient>>接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),num,fp); if(write_len!=num) { printf("ftpclient>>文件%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } // printf("ftpclient>>接收文件长度:%d\n",num); printf("ftpclient>>接收文件%s成功\n",file_name); fclose(fp); } //从服务器获取文件 close(tsock); return 0; }
服务器
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<sys/types.h> #include<unistd.h> #include<time.h> #include<signal.h> #include<stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> #define BUFLEN 1024 int SERVER_PORT = 23336 ; int my_BUFSIZ=1024; int FILE_NAME_MAX_SIZE=512; int LISTEN=30; int COMMOND_LEN=1024; int PIDNUM=3; void binner() { printf(" 【多进程版·ftpserver:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); /* 服务器发送文件 */ } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); printf("-s:最大连接量,默认3\n"); } #define maxn 10000000 int prime[maxn],x; _Bool vis[maxn]; void oulasai(int n) //欧拉筛 { memset(prime,0,sizeof(prime)); memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++) { if(!vis[i]) prime[x++]=i; for(int j=0;j<x;j++) { if(i*prime[j]>n) break; vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } } void send_prime_in_range(char *buf,int ssock) { //求出质数 memset(buf,'\0',sizeof(buf)); printf("ftpserver>>客户端要求的范围0-%s:\n",buf); int num = atoi(buf); x=0; int index=0; char res[my_BUFSIZ]; oulasai(num); memset(buf,'\0',sizeof(buf)); for(int i=0;i<x;i++) { sprintf(res,"%d",prime[i]); for(int j=0;j<strlen(res);++j) { buf[index++]=res[j]; } buf[index++]=','; } printf("ftpserver>>发送的字符串:%s\n",buf); send(ssock,buf,strlen(buf),0); } void commend_exec(int ssock,char *cmd) { DIR *dp=opendir("."); struct dirent *entry; char commd[COMMOND_LEN]; memset(commd,'\0',sizeof(commd)); while((entry = readdir(dp))!=NULL) { strcat(commd,entry->d_name); strcat(commd," "); } send(ssock,commd,strlen(commd),0); } static void handle_fork (int msock) { if(listen(msock,LISTEN)<0) { printf("ftpserver>>监听失败!\n"); exit(-1); } char buf [BUFLEN] ; time_t now; int ssock; struct sockaddr_in clientaddr; socklen_t len=sizeof(struct sockaddr_in); memset(&clientaddr,0,len); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock<0) { printf("ftpserver>>Accept Failed!"); exit(-1); } printf("\n*****************通信开始****************\n"); printf("ftpserver>>正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); //ftp_server(ssock); commend_exec(ssock,"."); char commd[COMMOND_LEN]; memset(commd,'\0',sizeof(commd)); if(recv(ssock,commd,sizeof(commd),0)<0) { printf("ftpserver>>接受客户端选择失败!\n"); exit(-1); } printf("ftpserver>>客户端的选择:%s\n",commd); if(strcmp(commd,"1")==0) { //下载文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',strlen(file_name)); if(recv(ssock,file_name,FILE_NAME_MAX_SIZE,0)<0) { printf("ftpserver>>接受文件名失败!\n"); exit(-1); } //接受文件体 FILE *fp = fopen(file_name,"w"); //printf("%s",file_name) if(fp==NULL) { printf("ftpserver>>文件\"%s\"不可打开\n",file_name); exit(-1); } char buffer[my_BUFSIZ]; memset(buffer,'\0',my_BUFSIZ); int num; while(num=recv(ssock,buffer,my_BUFSIZ,0)) { // printf("ftpclient>>接收文件长度:%d\n",num); if(num < 0) { printf("ftpserver>>接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),num,fp); if(write_len!=num) { printf("ftpserver>>文件%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } // printf("ftpclient>>接收文件长度:%d\n",num); printf("ftpclient>>接收文件%s成功\n",file_name); fclose(fp); } else if(strcmp(commd,"2")==0) { //接受文件 char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); if(recv(ssock, buffer, sizeof(buffer), 0)<0) { printf("ftpserver>>接收文件名失败\n"); exit(-1); } else { printf("ftpserver>>请求文件名%s\n",buffer); } char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); //将文件名从缓冲区buffer拷贝到文件名数组里面 strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer)); FILE * fp=fopen(file_name,"r"); if(fp==NULL) { printf("ftpserver>>文件%s不存在\n",file_name); } else { memset(buffer,'\0',my_BUFSIZ); int file_block_length=0; while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0) { //printf("ftpserver>>文件块大小:%d\n",file_block_length); if(send(ssock,buffer,file_block_length,0)<0) { printf("ftpserver>>文件:%s 发送失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("ftpserver>>文件%s发送成功\n",file_name); } } close(ssock); close(msock); return; } int main(int argc,char**argv) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { binner(); menue(); exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } else if(strcmp(argv[i],"-s")==0) { PIDNUM=atoi(argv[i+1]); } } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,PIDNUM); int msock; pid_t pid[PIDNUM]; msock=socket(AF_INET,SOCK_STREAM,0); if(msock<0) { printf("Create Socket Failed!\n"); exit(-1); } struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERVER_PORT); int ret; ret=bind(msock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in)); if(ret<0) { printf("Server Bind Port: %d Failed!\n",SERVER_PORT); exit(-1); } ret=listen(msock,LISTEN); if(ret<0) { printf("Listen Failed!\n"); exit(-1); } signal(SIGCLD,SIG_IGN); int i=0; for (i=0;i<PIDNUM;i++) { pid[i]=fork(); if(pid[i]==0) handle_fork(msock); } close(msock); return 0; }
运行效果