diff --git a/process_poll/client_size/Makefile b/process_poll/client_size/Makefile new file mode 100644 index 0000000..6e5e3b8 --- /dev/null +++ b/process_poll/client_size/Makefile @@ -0,0 +1,9 @@ +SOURCES:=$(wildcard *.c) +OBJS:=$(patsubst %.c,%.o,$(SOURCES)) +ELF:=client +CC:=gcc +CFLAGS:=-Wall +$(ELF):$(OBJS) + gcc $^ -o $@ +clean: + rm -rf $(OBJS) $(ELF) diff --git a/process_poll/client_size/client.c b/process_poll/client_size/client.c new file mode 100644 index 0000000..32bec76 --- /dev/null +++ b/process_poll/client_size/client.c @@ -0,0 +1,60 @@ +#include "func.h" + +int main(int argc,char** argv) +{ + check_args(argc,3); + int sfd; + sfd=socket(AF_INET,SOCK_STREAM,0); + check_error(-1,sfd,"socket"); + struct sockaddr_in ser; + bzero(&ser,sizeof(ser)); + ser.sin_family=AF_INET; + ser.sin_port=htons(atoi(argv[2])); //端口号转换为网络字节序 + ser.sin_addr.s_addr=inet_addr(argv[1]); + int ret; + ret=connect(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr)); + check_error(-1,ret,"connect"); + int len; + char buf[1000]={0}; + //接文件名 + recv_n(sfd,(char*)&len,4); + recv_n(sfd,buf,len); + + //接文件大小:用于打印百分比 + off_t file_size; + double down_load_size=0; + recv_n(sfd,(char*)&len,4); + recv_n(sfd,(char*)&file_size,len); + int fd=open(buf,O_RDWR|O_CREAT,0666); + check_error(-1,fd,"open"); + + //接文件内容,并按大小打印下载百分比 + off_t compare_size=file_size/100; + while(1) + { + ret=recv_n(sfd,(char*)&len,4); //服务器端若断开了,recv_n返回-1 + if(ret!=-1&&len>0) //recv_n返回-1,代表服务器断开了 + { + ret=recv_n(sfd,buf,len); + if(-1==ret) + { + printf("down percent %5.2f%s\n",down_load_size/file_size*100,"%"); + break; + } + write(fd,buf,len); + down_load_size=down_load_size+len; + if(down_load_size>compare_size) + { + printf("down percent %5.2f%s\r",down_load_size/file_size*100,"%"); + fflush(stdout); + compare_size=compare_size+file_size/100; + } + }else{ + printf("down percent %5.2f%s\n",down_load_size/file_size*100,"%"); + break; + } + } + close(fd); + close(sfd); +} + diff --git a/process_poll/client_size/func.h b/process_poll/client_size/func.h new file mode 100644 index 0000000..e701524 --- /dev/null +++ b/process_poll/client_size/func.h @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define check_args(a,b) {if(a!=b) {printf("error args\n");\ + return -1;}} +#define check_error(ret_val,ret,func_name) {if(ret_val==ret){\ + perror(func_name);return -1;}} +#define check_thread_error(ret,func_name) {if(0!=ret){\ + printf("%s is failed %d\n",func_name,ret);return -1;}} +typedef struct{ + pid_t pid; + int fds;//子进程的管道对端 + short busy_flag;//忙碌标志,0代表非忙碌,1代码忙碌 +}Data_t,*pData_t; + +int make_child(pData_t,int); +void child_handle(int); +int recv_fd(int,int*); +int send_fd(int,int); +int recv_n(int,char*,int); +#define FILENAME "file" +typedef struct{ + int len; + char buf[1000]; +}train; + diff --git a/process_poll/client_size/tran_n.c b/process_poll/client_size/tran_n.c new file mode 100644 index 0000000..c944e8c --- /dev/null +++ b/process_poll/client_size/tran_n.c @@ -0,0 +1,35 @@ +#include "func.h" +//循环发送 +int send_n(int sfd,char* p,int len) +{ + int total=0; + int ret; + while(total0) + { + ret=recv_n(sfd,buf,len); + if(ret==-1) + { + printf("download %5.2lf%s\n",download_size/file_size*100,"%"); + break; + } + write(fd,buf,len); + download_size=download_size+len; + end=time(NULL); + if(end-start>=1) + { + printf("download %5.2lf%s\r",download_size/file_size*100,"%"); + fflush(stdout); + start=end; + } + } + else //len等于0时,即读到了文件结束标志 + { + printf("download success 100%s\n","%"); + break; + } + } + close(fd); + close(sfd); + return 0; +} diff --git a/process_poll/client_time/func.h b/process_poll/client_time/func.h new file mode 100644 index 0000000..e701524 --- /dev/null +++ b/process_poll/client_time/func.h @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define check_args(a,b) {if(a!=b) {printf("error args\n");\ + return -1;}} +#define check_error(ret_val,ret,func_name) {if(ret_val==ret){\ + perror(func_name);return -1;}} +#define check_thread_error(ret,func_name) {if(0!=ret){\ + printf("%s is failed %d\n",func_name,ret);return -1;}} +typedef struct{ + pid_t pid; + int fds;//子进程的管道对端 + short busy_flag;//忙碌标志,0代表非忙碌,1代码忙碌 +}Data_t,*pData_t; + +int make_child(pData_t,int); +void child_handle(int); +int recv_fd(int,int*); +int send_fd(int,int); +int recv_n(int,char*,int); +#define FILENAME "file" +typedef struct{ + int len; + char buf[1000]; +}train; + diff --git a/process_poll/client_time/tran_n.c b/process_poll/client_time/tran_n.c new file mode 100644 index 0000000..c944e8c --- /dev/null +++ b/process_poll/client_time/tran_n.c @@ -0,0 +1,35 @@ +#include "func.h" +//循环发送 +int send_n(int sfd,char* p,int len) +{ + int total=0; + int ret; + while(total +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define check_args(a,b) {if(a!=b) {printf("error args\n");\ + return -1;}} +#define check_error(ret_val,ret,func_name) {if(ret_val==ret){\ + perror(func_name);return -1;}} +#define check_thread_error(ret,func_name) {if(0!=ret){\ + printf("%s is failed %d\n",func_name,ret);return -1;}} +typedef struct{ + pid_t pid; + int fds; //子进程的管道对端 + short busy_flag; //忙碌标志,0代表非忙碌,1代码忙碌 +}Data_t,*pData_t; + +int make_child(pData_t,int); +void child_handle(int); +int recv_fd(int,int*,int*); +int send_fd(int,int,int); +int tran_file(int); +int send_n(int,char*,int); + +#define FILENAME "file" + +typedef struct{ + int len; + char buf[1000]; +}train; + diff --git a/process_poll/service/send_fd.c b/process_poll/service/send_fd.c new file mode 100644 index 0000000..288deaa --- /dev/null +++ b/process_poll/service/send_fd.c @@ -0,0 +1,57 @@ +#include "func.h" +int send_fd(int sfd, int fd, int exit_flag) //exit_flag:用于通知子进程要退出了 +{ + struct msghdr msg; + bzero(&msg,sizeof(msg)); + char buf[10]="hello"; + struct iovec iov[2]; + iov[0].iov_base=buf; + iov[0].iov_len=5; + iov[1].iov_base=&exit_flag; + iov[1].iov_len=4; + + msg.msg_iov=iov; + msg.msg_iovlen=2; + struct cmsghdr *cmsg; + int len=CMSG_LEN(sizeof(int)); + cmsg=(struct cmsghdr *)calloc(1,len); + cmsg->cmsg_len=len; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int*)CMSG_DATA(cmsg)=fd; + msg.msg_control=cmsg; + msg.msg_controllen=len; + int ret; + ret=sendmsg(sfd,&msg,0); + check_error(-1,ret,"sendmsg"); + return 0; +} + +int recv_fd(int sfd, int *fd, int *exit_flag) +{ + struct msghdr msg; + bzero(&msg,sizeof(msg)); + char buf[10]="hello"; + struct iovec iov[2]; + iov[0].iov_base=buf; + iov[0].iov_len=5; + iov[1].iov_base=exit_flag; + iov[1].iov_len=4; + msg.msg_iov=iov; + msg.msg_iovlen=2; + struct cmsghdr *cmsg; + int len=CMSG_LEN(sizeof(int)); + cmsg=(struct cmsghdr *)calloc(1,len); + cmsg->cmsg_len=len; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + msg.msg_control=cmsg; + msg.msg_controllen=len; + int ret; + ret=recvmsg(sfd,&msg,0); + //收到传来的msg的内容,其包含iov数组内容(iov_base数据: 用于退出机制) + check_error(-1,ret,"recvmsg"); + *fd=*(int*)CMSG_DATA(cmsg); + return 0; +} + diff --git a/process_poll/service/service.c b/process_poll/service/service.c new file mode 100644 index 0000000..be567db --- /dev/null +++ b/process_poll/service/service.c @@ -0,0 +1,102 @@ +#include"func.h" +int exit_fds[2]; //定义成全局变量来传参(信号处理函数只能全局变量来传参) + +void sig_exit(int signum) +{ + char exit_flag='a'; + write(exit_fds[1],&exit_flag,1); +} + +int main(int argc,char *argv[]) +{ + check_args(argc,4); + pipe(exit_fds); //用于服务器退出机制 + + int process_num=atoi(argv[3]); //创建的进程数目 + pData_t p=(pData_t)calloc(process_num,sizeof(Data_t)); //创建指针并申请好空间,来保存创建的各个子进程的信息 + make_child(p,process_num); + + int sfd=socket(AF_INET,SOCK_STREAM,0); + int ret,i; + int reuse=1; + ret=setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int)); + check_error(-1,ret,"setsockopt"); + + int epfd=epoll_create(1); + struct epoll_event event,*evs; //注意:evs空间内还有一个TCP套接字sfd + evs=(struct epoll_event*)calloc(process_num+1,sizeof(struct epoll_event)); + event.events=EPOLLIN; + event.data.fd=sfd; + epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event); + for(i=0;i0) + //注意: t.len一定不能用strlen来算 + { + ret=send_n(new_fd,(char*)&t,4+t.len); + if(-1==ret) + { + goto end; + } + } + + //发送结束标志 + ret=send_n(new_fd,(char*)&t,4+t.len); //此时刚好t.len中存的就是0 + if(-1==ret) + { + goto end; + } +end: + close(new_fd); + return 0; +} diff --git a/process_poll/service/tran_n.c b/process_poll/service/tran_n.c new file mode 100644 index 0000000..ae493e6 --- /dev/null +++ b/process_poll/service/tran_n.c @@ -0,0 +1,35 @@ +#include "func.h" +//循环发送 +int send_n(int sfd,char* p,int len) +{ + int total=0; + int ret; + while(total