Socket网络编程: 多进程
编程实现创建2个新进程,每个新进程负责打印出:
(1)“Hello!My father is+父进程号”
(2)“I am +子进程号”
(3)50以内的质数
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdarg.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> int prime[15]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; int main(void) { printf("I'm your father,PID is %d.\n",getpid()); pid_t pid = fork(); if(pid == 0) { printf("I'm a first son.PID is %d.\n",getpid()); printf("Prime Numbers up to 50 :%d\n\n",prime[rand()%15]); exit(1);//若此处没有exit(1), 进程也会执行 pid_t pid2 = fork()语句,会出现孙进程 } pid_t pid2 = fork(); if(pid2 == 0){ printf("I'm a second son.PID is %d.\n",getpid()); printf("Prime Numbers up to 50 :%d\n\n",prime[rand()%15]); exit(1); } else if(pid != -1||pid2!=-1) { printf("Parent forked child process--%d.\n",pid); printf("Parent is waiting for child to exit.\n"); waitpid(pid,NULL,0); waitpid(pid2,NULL,0); printf("Child Process had exited.\n"); printf("Parent had exited.\n"); } else printf("Everything was done without error.\n"); return 0; }
编程实现创建3个新线程,每个新线程要求从主线程获得参数,并负责打印出:
(1)“Hello!My father is+父进程号”
(2)“I am +子进程号”
(3)判断参数是否为素数
#include <stdio.h> #include <stdlib.h> #include <pthread.h> //提供线程函数原型和数据结构的定义 #include <unistd.h> void thread(void *arg) { /*线程体函数*/ //pthread_detach(pthread_self());//子线程结束后,资源自动回收 sleep((int)arg); printf("I'm a son.TID is %lu.Father PID is %d.\n",pthread_self(),getpid()); int i=2; for(i=2;i*i<(int)arg;++i) { if((int)arg%i==0) { printf("The Numbers %d is not a prime number.\n\n",(int)arg); return NULL; } } printf("The Numbers %d is a prime number.\n\n",(int)arg); return NULL; } int main() { printf("This is the main process PID:%d,TID: %lu.\n\n",getpid(),pthread_self()); pthread_attr_t attr; //定义线程运行属性变量attr int i, ret; pthread_attr_init(&attr); //初始化线程运行属性变量attr pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);/*设置线程的分离状态*/ for(i=0;i<3;++i) { pthread_t pid; //定义线程标识符变量pid srand((unsigned int)time(0)); //printf("%d %d\n",args.l,args.num); int lao=rand()%100; ret=pthread_create(&pid, &attr, (void *) thread, (void *)lao); /*创建一个新线程执行线程体函数thread(),该线程的标识符为pid*/ if(ret!=0) { //若创建新线程失败,则输出出错提示并退出程序 printf ("Create pthread error!\n"); exit (1); } } sleep(10); pthread_attr_destroy(&attr); //去初始化线程运行属性变量attr printf("This is the main process PID:%d exit~~~\n",getpid()); pthread_exit(NULL); return 0; //调用return()函数返回整型值0作为main()的返回值 }
客户端获得服务器时间,发送文件名可请求指定文件
客户端
#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(" 【多进程版·文件传输助手: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); } printf("Create Socket Success fully!\n"); 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); } //获取服务器的时间 socklen_t len; char buf[BUFLEN]; memset(buf, '\0',sizeof(buf)); strcpy(buf,"TIME"); send(tsock,buf,strlen(buf),0); memset(buf,'\0',sizeof(buf)); len=recv(tsock,buf,BUFLEN,0); if(len>0) { printf("服务器系统时间是:%s\n",buf); } //从服务器获取文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); //向服务器发送buffer中的数据,buffer中放的是文件的名字 int num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //接受文件 FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } memset(buffer,'\0',my_BUFSIZ); while(num=recv(tsock,buffer,my_BUFSIZ,0)) { printf("接收文件长度:%d\n",num); if(num < 0) { printf("接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),num,fp); if(write_len!=num) { printf("文件:%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } printf("接收文件长度:%d\n",num); printf("接收文件:%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> #define BUFLEN 1024 #define PIDNUM 3 int SERVER_PORT = 23336 ; int my_BUFSIZ=1024; int FILE_NAME_MAX_SIZE=512; int LISTEN=30; void binner() { printf(" 【多进程版·文件传输助手: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:最大连接量,默认30\n"); } static void handle_fork (int msock) { if(listen(msock,LISTEN)<0) { printf("监听失败!\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("Accept Failed!"); exit(-1); } printf("\n*****************通信开始****************\n"); printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); //发送本地时间 memset(buf,'\0',sizeof(buf)); if(recv(ssock,buf,BUFLEN,0)>0 && !strncmp(buf,"TIME",4)) { memset(buf,'\0',sizeof(buf)); now=time(NULL); sprintf(buf,"%24s\r\n",ctime(&now)); send(ssock,buf,strlen(buf),0); //接受文件名 char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); if(recv(ssock, buffer, sizeof(buffer), 0)<0) { printf("接收文件名失败\n"); exit(-1); } else { printf("请求文件名>>%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("文件:%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("文件块大小:%d\n",file_block_length); if(send(ssock,buffer,file_block_length,0)<0) { printf("文件:%s 发送失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%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) { LISTEN=atoi(argv[i+1]); } } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN); 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; }
效果图:
通过服务器进行字母的大小写转换功能+文件传输
客户端:
#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(" 【多进程版·文件传输助手: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); } printf("Create Socket Success fully!\n"); 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); } //向服务器发送字符 socklen_t len; char buf[BUFLEN]; memset(buf, '\0',sizeof(buf)); printf("请输入要转换的字符\n"); gets(buf); send(tsock,buf,strlen(buf),0); memset(buf,'\0',sizeof(buf)); len=recv(tsock,buf,BUFLEN,0); if(len>0) { printf("转换后的字符是:%s\n",buf); } //从服务器获取文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); //向服务器发送buffer中的数据,buffer中放的是文件的名字 int num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //接受文件 FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } memset(buffer,'\0',my_BUFSIZ); while(num=recv(tsock,buffer,my_BUFSIZ,0)) { printf("接收文件长度:%d\n",num); if(num < 0) { printf("接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),num,fp); if(write_len!=num) { printf("文件:%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } printf("接收文件长度:%d\n",num); printf("接收文件:%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> #define BUFLEN 1024 #define PIDNUM 3 int SERVER_PORT = 23336 ; int my_BUFSIZ=1024; int FILE_NAME_MAX_SIZE=512; int LISTEN=30; void binner() { printf(" 【多进程版·文件传输助手: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:最大连接量,默认30\n"); } static void handle_fork (int msock) { if(listen(msock,LISTEN)<0) { printf("监听失败!\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("Accept Failed!"); exit(-1); } printf("\n*****************通信开始****************\n"); printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); //字符转换 memset(buf,'\0',sizeof(buf)); if(recv(ssock,buf,BUFLEN,0)>0) { printf("客户端要求转换的字符串:%s\n",buf); for(int i=0;i<strlen(buf);++i) { if('a'<=buf[i]&&buf[i]<='z') { buf[i]-=32; } } printf("转换后的字符串:%s\n",buf); send(ssock,buf,strlen(buf),0); //接受文件名 char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); if(recv(ssock, buffer, sizeof(buffer), 0)<0) { printf("接收文件名失败\n"); exit(-1); } else { printf("请求文件名>>%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("文件:%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("文件块大小:%d\n",file_block_length); if(send(ssock,buffer,file_block_length,0)<0) { printf("文件:%s 发送失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%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) { LISTEN=atoi(argv[i+1]); } } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN); 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; }
通过服务器求出所给数字之内的质数
客户端:
#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(" 【多进程版·文件传输助手: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); } printf("Create Socket Success fully!\n"); 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); } //向服务器数字最大值 socklen_t len; char buf[BUFLEN]; memset(buf, '\0',sizeof(buf)); printf("请输入n:"); gets(buf); send(tsock,buf,strlen(buf),0); memset(buf,'\0',sizeof(buf)); len=recv(tsock,buf,BUFLEN,0); if(len>0) { printf("0-n的质数:%s\n",buf); } //从服务器获取文件 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); //向服务器发送buffer中的数据,buffer中放的是文件的名字 int num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //接受文件 FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } memset(buffer,'\0',my_BUFSIZ); while(num=recv(tsock,buffer,my_BUFSIZ,0)) { printf("接收文件长度:%d\n",num); if(num < 0) { printf("接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),num,fp); if(write_len!=num) { printf("文件:%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } printf("接收文件长度:%d\n",num); printf("接收文件:%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> #define BUFLEN 1024 #define PIDNUM 3 int SERVER_PORT = 23336 ; int my_BUFSIZ=1024; int FILE_NAME_MAX_SIZE=512; int LISTEN=30; void binner() { printf(" 【多进程版·文件传输助手: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:最大连接量,默认30\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; } } } static void handle_fork (int msock) { if(listen(msock,LISTEN)<0) { printf("监听失败!\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("Accept Failed!"); exit(-1); } printf("\n*****************通信开始****************\n"); printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); //求出质数 memset(buf,'\0',sizeof(buf)); if(recv(ssock,buf,BUFLEN,0)>0) { printf("客户端要求的范围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("发送的字符串:%s\n",buf); send(ssock,buf,strlen(buf),0); //接受文件名 char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); if(recv(ssock, buffer, sizeof(buffer), 0)<0) { printf("接收文件名失败\n"); exit(-1); } else { printf("请求文件名>>%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("文件:%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("文件块大小:%d\n",file_block_length); if(send(ssock,buffer,file_block_length,0)<0) { printf("文件:%s 发送失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%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) { LISTEN=atoi(argv[i+1]); } } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN); 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; }