当前位置: 首页 > news >正文

合肥seo网站建设费用站长工具seo推广

合肥seo网站建设费用,站长工具seo推广,网站建设属于什么税,宁波制作手机网站项目需求 客户端能够通过调用“get”指令#xff0c;来获取服务器的文件客户端能通过“server_ls”指令#xff0c;来获取服务器路径下的文件列表客户端能通过“server_cd”指令#xff0c;进入服务器路径下的某文件夹客户端可以通过“upload”指令#xff0c;上传自己的本…项目需求 客户端能够通过调用“get”指令来获取服务器的文件客户端能通过“server_ls”指令来获取服务器路径下的文件列表客户端能通过“server_cd”指令进入服务器路径下的某文件夹客户端可以通过“upload”指令上传自己的本地文件到服务器客户端可以通过“client_ls”指令来查看本地路径下的文件列表客户端可以通过“client_cd”指令进入本地路径下的某文件夹 预备知识 strtok函数用于字符串的分割详见C语言 字符串分割_c语言分割字符串_Genven_Liang的博客-CSDN博客sprintf函数用于字符串的拼接详见sprintf()函数简要介绍_sprintf函数_做最完美的自己的博客-CSDN博客  char s1{A,B,C}; sprintf(str,aaa %.*s,2,s1); //取字符串s1的前2个字符并和“aaa ”拼接 执行完后str字符串为“aaa AB” chdir函数。system(cd XXX)并不能成功修改当前程序的路径因为system本质上是fork了一个子进程在子进程中执行指令所以cd是在子进程中执行的和当前程序无关想要成功修改当前的路径所以需要使用chdir(XXX)这样就可以修改当前的目录了详见在程序里面执行system(“cd /某个目录“)为什么路径切换不成功_一口Linux的博客-CSDN博客recv函数和send函数一组用于网络套接字的收发和read/write不同read/write返回的是已读/写的字节数而send/recv函数返回的是以接受/发送的字节数所以当网络连接关闭时recv会返回0所以recv函数可以用于检测网络连接是否关闭但是客户端似乎还是要使用进程间通讯来退出find指令可以用来判断一个文件是否存在显然也可以直接用system调用详见超详解Linux系统find命令用法_linux命令find用法详解_是大姚呀的博客-CSDN博客使用lseek函数计算文件大小 size lseek(fd_file, 0L, SEEK_END); 实现思路 “get”指令实现思路 对于客户端 检测用户是否输入了“get”若输入之后就让服务器发送文件过来并自己创建一个同名文件写入服务器发来的数据 对于服务端 检测客户端是否发来了“get”如果是就检测服务器要哪个文件并将文件的内容全部读取然后发给客户端 “server_ls”指令实现思路 对于客户端 啥也不用干输入指令后等着接受 对于服务端 检测客户端是否发来了“server_ls”如果是就popen执行“ls -l”并读取运行结果将结果发给客户端 “server_cd”指令实现思路 对于客户端 啥也不用干输入指令后等着接受 对于服务端 测客户端是否发来了“server_cd”如果是就检测后面cd的地址然后调用chdir函数执行这个地址然后popen执行“pwd”并读取运行结果将结果发给客户端 “upload”指令实现思路 对于客户端 检测用户是否输入了“upload”若输入之后就检测用户要上传哪个文件将文件内容全部复制并发送给服务器 对于服务端 检测客户端是否发来了“upload”如果是就检测用户上传的文件名并接受所有文件数据然后创建一个同名的文件将数据全部写进去 “client_ls”指令实现思路 对于客户端 检测用户是否输入了“clien_ls”若输入之后就调用system函数执行“ls -l” 对于服务端 啥也不用干 “client_cd”指令实现思路 对于客户端 检测用户是否输入了“clien_cd”若输入之后就检测cd之后的地址然后调用chdir函数执行这个地址然后调用system函数执行“pwd” 对于服务端 啥也不用干 具体代码 注意为了接收到带空格的字符串我使用了fgets函数但是fgets函数在长度足够的情况下会将换行符“\n”也读进字符串所以strlen也会多计算一位所以服务器使用fgets得到字符串并发送给客户端客户端接受之后打印就不需要再换行了反之亦然服务器的接收端再接受之后也不需要再加换行符了 切记切记切记以下的写法是完全错误的 char *file_name; char *readbuf tyytt;file_name readbuf; //错错错错错错错错 原因: 字符串常量本质是一个指针而变量名相当于首地址这句话相当于地址的赋值所以只要写了这句代码不管readbuf的值变成了什么样file_name就会跟着变成什么样所以字符串的赋值一定要用strcpy血与泪的教训自查了好久... 而使用strcpy则要注意第一个参数不能是字符串常量而需要是字符串变量 同时在代码逻辑中服务端对于flag_upload的置位和对其的判断都在子进程中所以可以直接用if判断但是对于客户端flag_get的置位在负责写的父进程对flag_get的判断却在负责读的子进程正如一直强调的fork之后的存储空间是独立的所以父进程将flag置位子进程并不知道所以不能简单的使用flag_get需要使用进程间的通信来解决同样file_name在服务端可以直接修改但是客户端也需要使用进程间通信 在子进程两个while中使用进程间通信就会涉及到上节出现的问题即负责发数据的父进程写入fifo后负责接数据的子进程还在阻塞等待服务器的消息程序无法运行到检测fifo的代码处解决方法就是让服务器立刻回复一个数据对于file_name的传输服务器正好要回复file_name对于是否要跳转到get_handler服务器正好要发送文件的内容。所以在这个代码逻辑中不需要额外再设置服务器回复如果在日后遇到了同样的情况服务器又不需要回复什么那么记得要随便写一条内容来回复。 server.c #include sys/types.h #include sys/socket.h #include stdio.h #include unistd.h #include netinet/in.h #include arpa/inet.h #include linux/in.h #include string.h #include sys/wait.h #include stdlib.h #include sys/stat.h #include errno.h #include fcntl.hint flag_upload 0; int flag_exist 0; char *file_nameNULL;int cmd_handler(int fd, char readbuf[10000]) {int fd_file; 判断为get命令后用来存放即将发送的文件的文件标识符int size; //判断为get命令后用来存放即将发送的文件的大小char *file_buf NULL; //判断为get命令后用来存放即将发送的文件的内容int ret;int i 0;char result[4096] {0}; //用来存放popen执行指令的结果FILE *fp; //popen返回的文件流标识符char str[10000]; //将读到的数据备份在这里char* stat[5] {NULL,NULL,NULL,NULL,NULL}; //用来存放拆分后的字符串char cmd[128]; //用来存放加工后的字符串比如去除“\n”比如再加上“./”strcpy(str,readbuf); //由于字符串的首地址是字符串的名字所以此时相当于传入的地址所有对字符串的操作都会影响它所以需要进行备份先备份再对备份的数据进行数据处理就不会影响原数据了char* ptr strtok(str, ); //通过空格符号分隔字符串for(; ptr ! NULL; ){stat[i] ptr;//printf(%s\n, stat[i]);i;ptr strtok(NULL, );}if(strcmp(stat[0],get)0){ //如果是get命令sprintf(cmd, find . -name %.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nfp popen(cmd,r); //运行指令查看文件是否存在fread(result, sizeof(char), sizeof(result), fp);pclose(fp);if(strlen(result)0){ret write(fd,file not exist\n,20); //不存在就发送给客户端来通知if(ret -1){perror(write);return 1;}return 1;}else{sprintf(cmd, ./%.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nret write(fd,cmd,strlen(cmd)); //如果存在就先将文件名传给客户端if(ret -1){perror(write);return 1;}}memset(result,0,sizeof(result));//sleep(2);sprintf(cmd, ./%.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nfd_file open(cmd,O_RDWR); //然后打开这个文件将内容全部复制size lseek(fd_file, 0L, SEEK_END);printf(file size %d\n,size);file_buf (char *)malloc(sizeof(char)*size 1);lseek(fd_file, 0, SEEK_SET);ret read(fd_file,file_buf,size);if(ret -1){perror(read2);return 1;}close(fd_file);ret write(fd,file_buf,size); //将文件的内容发送给客户端if(ret -1){perror(write);return 1;}}else if(strcmp(stat[0],server_cd)0){ //如果是server_cd命令sprintf(cmd, %.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nchdir(cmd); //将目录cd到客户端要求的位置fp popen(pwd,r); //然后执行pwd将结果发回给客户端fread(result, sizeof(char), 1024, fp);pclose(fp);ret write(fd,result,strlen(result));if(ret -1){perror(write);return 1;}memset(result,0,sizeof(result));}else if(strcmp(stat[0],upload)0){ //如果是upload命令flag_upload 1; //表示准备uploadsprintf(cmd, ./%.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nfile_name cmd; //接收客户端发来的即将发送过来的文件名}else if(strcmp(stat[0],exist)0){flag_exist 1; //和准备upload的标识符配合使用只有客户端判断用户输入的upload文件存在时才会发送exist此时服务端将文件存在的标识符也置1}else if(strcmp(stat[0],server_ls\n)0){ //如果是server_ls命令fp popen(ls -l,r); //执行ls-l命令然后把结果发回客户端fread(result, sizeof(char), 1024, fp);pclose(fp);ret write(fd,result,strlen(result));if(ret -1){perror(write);return 1;}memset(result,0,sizeof(result));}else if(strcmp(stat[0],quit\n)0){ //如果客户端打出了quitret write(fd,Bye\n,4); //立刻回发一个Bye目的是让客户端取消接收阻塞然后成功从FIFO读取到退出信息if(ret -1){perror(write);return 1;}}return 0; }void upload_handler(char readbuf[10000]) //upload指令如果被最终判断为可以执行则会调用这个函数来通过客户端发来的文件名和文件内容来创建文件 {int fd_file;int n_write;fd_file open(file_name,O_RDWR|O_CREAT|O_TRUNC,S_IRWXU);n_write write(fd_file, (char *)readbuf, strlen((char *)readbuf));printf(create new file %s, %d bytes have been written\n,file_name, n_write);close(fd_file);}int main(int argc, char **argv) //main函数 {int conn_num 0;int flag 0;int sockfd;int conn_sockfd;int ret;int n_read;int n_write;int len sizeof(struct sockaddr_in);char readbuf[10000];char msg[10000];pid_t fork_return;pid_t fork_return_1;struct sockaddr_in my_addr;struct sockaddr_in client_addr;memset(my_addr,0,sizeof(struct sockaddr_in));memset(client_addr,0,sizeof(struct sockaddr_in));if(argc ! 3){printf(param error!\n);return 1;}//socketsockfd socket(AF_INET,SOCK_STREAM,0);if(sockfd -1){perror(socket);return 1;}else{printf(socket success, sockfd %d\n,sockfd);}//bindmy_addr.sin_family AF_INET;my_addr.sin_port htons(atoi(argv[2]));//host to net (2 bytes)inet_aton(argv[1],my_addr.sin_addr); //char* format - net formatret bind(sockfd, (struct sockaddr *)my_addr, len);if(ret -1){perror(bind);return 1;}else{printf(bind success\n);}//listenret listen(sockfd,10);if(ret -1){perror(listen);return 1;}else{printf(listening...\n);}while(1){//acceptconn_sockfd accept(sockfd,(struct sockaddr *)client_addr,len);if(conn_sockfd -1){perror(accept);return 1;}else{printf(accept success, client IP %s\n,inet_ntoa(client_addr.sin_addr));}fork_return fork();if(fork_return 0){//father keeps waiting for new request//do nothing }else if(fork_return 0){perror(fork);return 1;}else{//son deals with requestwhile(1){//readmemset(readbuf,0,sizeof(readbuf));ret recv(conn_sockfd, readbuf, sizeof(readbuf), 0);if(ret 0){ //如果recv函数返回0表示连接已经断开printf(client has quit\n);close(conn_sockfd);break;}else if(ret -1){perror(recv);return 1;}if(flag_upload 1 flag_exist 1){ //当准备upload的标识位和文件存在的标识位同时置1时才会进入这段代码flag_exist 0; //立刻将两个标识位重新置0flag_upload 0;upload_handler(readbuf); //并执行upload所对应的函数}cmd_handler(conn_sockfd, readbuf); //对客户端发来的消息进行判断的总函数//printf(\nclient: %s,readbuf); //dont need to add\n}exit(2);}}return 0; } client.c #include sys/types.h #include sys/socket.h #include stdio.h #include unistd.h #include netinet/in.h #include arpa/inet.h #include linux/in.h #include string.h #include sys/wait.h #include stdlib.h #include sys/stat.h #include errno.h #include fcntl.hint flag_quit 0;int cmd_handler(int fd,char msg[10000]) {int fd_file; //如果判断为upload,则用来存放即将发送的文件的标识符int size; //如果判断为upload,则用来存放即将发送的文件的大小int fd_fifo; //用来存放fifo的标识符char *fifo_msg quit;char *fifo_msg_get get;char *file_buf NULL; //如果判断为upload,则用来存放即将发送的文件的内容char result[4096] {0}; //用来存放popen函数调用指令后的结果FILE *fp; //用来存放popen返回的标识符int ret;int i 0;char str[10000]; //用来存放客户端读取数据的备份方便进行数据操作char* stat[5] {NULL,NULL,NULL,NULL,NULL}; //用来存放分隔后的字符串char cmd[128]; //用来存放进行加工后的字符串strcpy(str,msg); //so split will not affect original data原因详见server.cchar* ptr strtok(str, ); //用空格分隔字符串for(; ptr ! NULL; ){stat[i] ptr;//printf(%s\n, stat[i]);i;ptr strtok(NULL, );}if(strcmp(stat[0],client_ls\n)0){ //如果是client_ls指令system(ls -l); //执行ls-l}else if(strcmp(stat[0],client_cd)0){ //如果是client_cd指令sprintf(cmd, %.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nchdir(cmd); //cd到用户指定的目录system(pwd); //然后执行pwd}else if(strcmp(stat[0],get)0){ //如果是get指令fd_fifo open(./fifo,O_WRONLY); //阻塞的只写打开fifo阻塞直到fifo被只读打开write(fd_fifo,fifo_msg_get,strlen(fifo_msg_get)); //向fifo中写信息告诉负责读的子进程用户调用了get指令close(fd_fifo);}else if(strcmp(stat[0],quit\n)0){ //如果是quit指令//printf(quit detected!\n);fd_fifo open(./fifo,O_WRONLY); //阻塞的只写打开fifo阻塞直到fifo被只读打开write(fd_fifo,fifo_msg,strlen(fifo_msg)); //向fifo中写信息告诉负责读的子进程用户调用了quit指令close(fd_fifo);close(fd); //关闭套接字wait(NULL); //等待子进程退出flag_quit 1; //将退出标识符置1}else if(strcmp(stat[0],upload)0){ //如果是upload指令sprintf(cmd, find . -name %.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nfp popen(cmd,r); //通过调用find查看要上传的文件是否存在fread(result, sizeof(char), sizeof(result), fp);pclose(fp);if(strlen(result)0){printf(file not exit!\n);return 1;}else{ret write(fd,exist,20); //只有文件存在才向服务器发送existif(ret -1){perror(write);return 1;}}memset(result,0,sizeof(result));sprintf(cmd, ./%.*s,(int)(strlen(stat[1])-1),stat[1]); //remove \nfd_file open(cmd,O_RDWR); //打开要发送的文件将内容全部复制发送给服务器size lseek(fd_file, 0L, SEEK_END);printf(file size %d\n,size);file_buf (char *)malloc(sizeof(char)*size 1);lseek(fd_file, 0, SEEK_SET);ret read(fd_file,file_buf,size);if(ret -1){perror(read2);return 1;}close(fd_file);sleep(2); //ensure the flag_upload is set to 1 in serverret write(fd,file_buf,size);if(ret -1){perror(write);return 1;}}return 0; }void get_handler(char *file_name, char readbuf[10000]) //当确定要执行get命令时会调用这个函数通过服务器发来的文件名和文件内容创建文件 {int fd_file;int n_write;fd_file open(file_name,O_RDWR|O_CREAT|O_TRUNC,S_IRWXU);n_write write(fd_file, (char *)readbuf, strlen((char *)readbuf));printf(\ncreate new file %s, %d bytes have been written\n,file_name, n_write);close(fd_file);}int main(int argc, char **argv) //main函数 {int cnt 0;char file_name[20]{0};int no_print 0;int sockfd;int ret;int n_read;int n_write;char readbuf[10000];char msg[10000];int fd; //fifochar fifo_readbuf[20] {0};int fd_get;pid_t fork_return;if(argc ! 3){printf(param error!\n);return 1;}struct sockaddr_in server_addr;memset(server_addr,0,sizeof(struct sockaddr_in));//socketsockfd socket(AF_INET,SOCK_STREAM,0);if(sockfd -1){perror(socket);return 1;}else{printf(socket success, sockfd %d\n,sockfd);}//connectserver_addr.sin_family AF_INET;server_addr.sin_port htons(atoi(argv[2]));//host to net (2 bytes)inet_aton(argv[1],server_addr.sin_addr); ret connect(sockfd, (struct sockaddr *)server_addr, sizeof(struct sockaddr_in));if(ret -1){perror(connect);return 1;}else{printf(connect success!\n);}//fifoif(mkfifo(./fifo,S_IRWXU) -1 errno ! EEXIST){perror(fifo);}//forkfork_return fork();if(fork_return 0){//father keeps writing msgwhile(1){//writememset(msg,0,sizeof(msg));fgets(msg,sizeof(msg),stdin);n_write write(sockfd,msg,strlen(msg));cmd_handler(sockfd,msg); //负责处理并判断用户输入的总函数if(flag_quit 1){ //如果退出标识符被置位flag_quit 0;break; //则父进程退出循环然后退出}if(n_write -1){perror(write);return 1;}else{//printf(%d bytes msg sent\n,n_write);}}}else if(fork_return 0){perror(fork);return 1;}else{//son keeps reading while(1){fd open(./fifo,O_RDONLY|O_NONBLOCK); //非阻塞的只读打开FIFOlseek(fd, 0, SEEK_SET); //光标移到最前read(fd,fifo_readbuf,20); //从FIFO读取数据if(strcmp(fifo_readbuf,quit)0){ //如果FIFO中是quitexit(1); //则子进程立刻退出}else if(cnt 1){ //如果判断为get指令服务器将发送两次消息第一次为文件名第二次为文件内容使用cnt和fifo消息的读取来配合第一次将读来的值赋值给文件名第二次将读来的值作为文件内容传入get_handler用来创建文件get_handler(file_name, readbuf);cnt 0;no_print 0; //将静止打印标识符重新归0}else if(strcmp(fifo_readbuf,get)0){ //如上一个else if的注释所言能进入这个循环说明是get指令后服务器发送的第一次消息strcpy(file_name,readbuf); //重要字符串的赋值要用strcpy!!if(strcmp(file_name,file not exist\n)0){ //如果服务器第一次发来的消息是文件不存在则啥都不用干就当这次get没发生//do nothing}else{ //此时将cnt使得服务器下一次发送的消息会被准确的判断为文件的内容cnt;no_print 1; //并且使得静止打印的标识符为1防止在界面中打印文件内容}}memset(fifo_readbuf,0,sizeof(fifo_readbuf)); //重要不要忘记//readmemset(readbuf,0,sizeof(readbuf));n_read read(sockfd,readbuf,sizeof(readbuf));if(ret -1){perror(read1);return 1;}else if(ret ! -1 no_print 0){ //只有静止打印标识符为0时才打印服务器发来的消息为了防止当get指令生效时将服务器发来的大量文件内容打在屏幕上影响观感printf(\nserver: %s,readbuf); //dont need to add\n}}}return 0; } 对于客户端中使用FIFO配合服务器的回复实现get指令的详细说明 实现效果 编译并运行服务端和客户端建立连接 “server_ls”指令演示 观察server的目录来验证 “server_cd”指令演示 “client_ls”指令演示 观察client的目录来验证 “client_cd”指令演示 “upload”指令演示 客户端 服务端 再看服务端的目录可见文件已经被成功上传 也可以用“server_ls” 来验证  “get”指令演示 客户端 服务端 再看客户端的目录可见文件已经被成功获取 也可以用“client_ls” 来验证 “quit”指令演示 客户端 服务端
http://www.zqtcl.cn/news/957942/

相关文章:

  • wordpress 怎么手动更新宝安网站 建设seo信科
  • 腾讯的网站建设用了多少钱找人合伙做网站平台
  • 企业网站功能模块介绍服务器免费体验
  • 小程序制作收款网站结构优化的优化包括
  • 北京市建设工程质监站网站poi player wordpress
  • php网站开发工程师招聘网自己做小程序要钱吗
  • 两学一做考试网站空间网
  • 齐诺网站建设东莞网站建设做网站集团网站群
  • 网站运营策略如何做软件网站开发培训
  • 数据库型网站wordpress上传工具
  • 太原建站公司模板宁波seo公司哪家好
  • 电商网站都是用什么做的承接电商网站建设
  • c2c网站代表有哪些怎样制作个人网站
  • wordpress linux 建站安丘市建设局官方网站
  • 谁给个好网站硬件开发是什么
  • 海外网站加速器免费长春做网站优化哪家好
  • 建立网站需要多长钱电脑网页设计培训
  • 给网站划分栏目邢台做网站优化费用
  • 网群企业网站管理系统红塔区住房和城乡建设局网站
  • 濮阳网站建设在哪做沈阳百度网站的优点
  • 网站上如何做问卷调查温州建设局官方网站
  • 做一件代发哪个网站好具有品牌的福州网站建设
  • 邢台移动端网站建设犀牛建模教程
  • 华池网站建设广西柳州市
  • 泰安网站建设推荐软件商店电脑版官方下载
  • 站长平台网站报价单模板表格
  • 织梦做的网站老是被黑杭州网站设计询问蓝韵网络
  • wordpress手机版如何设置福鼎整站优化
  • 网站建设小程序定制开发北京东宏建设网站
  • 网站制作还花钱网站图怎么做