博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20155301信息安全系统设计基础第三次实验
阅读量:6364 次
发布时间:2019-06-23

本文共 10621 字,大约阅读时间需要 35 分钟。

信息安全系统设计基础第三次实验

实验一

任务要求

1)学习使用Linux命令wc(1)

2)基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端

3)客户端传一个文本文件给服务器

4)服务器返加文本文件中的单词数

实验步骤

首先要在Linux中查看wc命令

1072918-20171119163103577-2019850717.png

从中我们可以得知wc的命令是输出文章中的单词或者字符个数

然后wc中有很多命令参数,它们各自的作用如下

-c 统计字节数。

-l 统计行数。

-m 统计字符数。这个标志不能与 -c 标志一起使用。

-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

-L 打印最长行的长度。

-help 显示帮助信息

--version 显示版本信息

  • 实现-c功能,利用stat函数实现

    1072918-20171119163115468-96760827.png

  • 实现-m功能,就是利用while(fgets(fp,buf,N)){i++}的方式实现
  • 实现-l功能,就是利用读文件,当读到'\n'的时候,就加1
  • 实现-w功能,也是读文件,但是在读到'\t' '\n'的时候加1

    运行代码

    客户端

#include
#include
#include
#include
#include
#include
#include
#include
#define HELLO_WORLD_SERVER_PORT 155339 #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 512 int mywc(char file_name[],int choose);int main(int argc, char **argv) { FILE *fp; if (argc < 2) { printf("Usage: ./%s ServerIPAddress\n", argv[0]); exit(1); } // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 struct sockaddr_in client_addr; bzero(&client_addr, sizeof(client_addr)); client_addr.sin_family = AF_INET; // internet协议族 client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket < 0) { printf("Create Socket Failed!\n"); exit(1); } // 把客户端的socket和客户端的socket地址结构绑定 if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) { printf("Client Bind Port Failed!\n"); exit(1); } // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; // 服务器的IP地址来自程序的参数 if (inet_aton(argv[1], &server_addr.sin_addr) == 0) { printf("Server IP Address Error!\n"); exit(1); } server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); socklen_t server_addr_length = sizeof(server_addr); // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) { printf("Can Not Connect To %s!\n", argv[1]); exit(1); } //bzero(argv[2], sizeof(argv[2])); if((fp = fopen(argv[2],"r"))==NULL) { printf("Failure to open %s\n",argv[2]); exit(0); } char buffer[BUFFER_SIZE]; bzero(buffer, sizeof(buffer)); char ch; int i=0; while((ch=fgetc(fp))!=EOF) { buffer[i++]=ch; if(i>=BUFFER_SIZE) { if((send(client_socket, buffer, BUFFER_SIZE, 0))==-1) { printf("发送文件失败\n"); } bzero(buffer, sizeof(buffer)); i=0; } } if(i
#### 服务器#include
#include
#include
#include
#include
#include
#include
#include
#include
#define HELLO_WORLD_SERVER_PORT 155339 #define LENGTH_OF_LISTEN_QUEUE 20 #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 512 struct message{ int lines; int words; int max_line_length; int size; int chars; }info; void error_print(char str[]){ printf("Error:%s",str); } void init(char filename[]){ struct stat get_message = {}; FILE *fp; int ret_stat = stat(filename,&get_message);/*用stat函数读取filenmae文件的信息,并将结果写到get_message结构体中*/ if(ret_stat == -1){//stat函数不出错则进行信息输出 error_print(filename); return ; } mode_t mode = get_message.st_mode; //接收文件信息,用于下面判断是不是目录 int length = 0; if(S_ISDIR(mode)) //如果是目录,输出错误 printf("Error %s is dir\n0\t0\t0\t%s",filename,filename); else{ info.size = get_message.st_size; //文件字节大小 wc -c fp = fopen(filename,"r"); //以只读方式打开指定文件 char ch; int flag = 0; while((ch = fgetc(fp))!=EOF){ //一直读到文件尾 info.chars++; //字符数加1 wc -m if(ch != '\n'){ length++; //记录当前行的长度 wc -L } if(ch == '\n'){ info.lines ++; //行数加1 wc -l if(length>info.max_line_length) info.max_line_length = length; //更新最大长度 length = 0; } if(ch == '\t' || ch == ' ' || ch == '\n'){ flag = 0; //计算单词数 wc -w continue; } else{ if(flag == 0){ info.words++; //计算单词数 wc -w flag = 1; } } } fclose(fp); } } int mywc(int argc,char *argv[]){ if(argc == 2){ if(argv[1][0] != '-'){ init(argv[1]); //printf("%d %d %d %s\n",info.lines,info.words,info.size,argv[1]); return 0; } } else if(argc == 3){ init(argv[2]); } int num; while((num = getopt(argc,argv,"lwmcL"))!=-1){ switch(num){ case 'l': printf("%d\n",info.lines); break; case 'w': printf("%d\n",info.words); break; case 'm': printf("%d\n",info.chars); break; case 'c': printf("%d\n",info.size); break; case 'L': printf("%d\n",info.max_line_length); break; } } if(argc != 2 && argv[1][0] != '-') //一定要判断,否则会越界 printf("%s\n",argv[2]); return 0; }int main(int argc, char **argv) { // set socket's address information // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口 struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htons(INADDR_ANY); server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); // create a stream socket // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口 int server_socket = socket(PF_INET, SOCK_STREAM, 0); if (server_socket < 0) { printf("Create Socket Failed!\n"); exit(1); } // 把socket和socket地址结构绑定 if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) { printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT); exit(1); } // server_socket用于监听 if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)) { printf("Server Listen Failed!\n"); exit(1); } // 服务器端一直运行用以持续为客户端提供服务 // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept // 接受此请求,同时将client端的地址和端口等信息写入client_addr中 struct sockaddr_in client_addr; int length = sizeof(client_addr); int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length); printf("连接到客户端\n"); if (new_server_socket < 0) { printf("Server Accept Failed!\n"); } FILE *fp; if((fp = fopen("1.txt","w"))==NULL) { printf("Failure to open recvfile\n"); exit(0); } //接受来自客户端的文件 char buffer[BUFFER_SIZE]; bzero(buffer, sizeof(buffer)); length=0; while( length = recv(new_server_socket, buffer, BUFFER_SIZE, 0) ) { if(length<0) { printf("接受文件出错\n"); exit(0); } if(fwrite(buffer,sizeof(char),length,fp)

运行结果:

1072918-20171119163124546-194897775.png

客户端发给服务器一个文章,服务器调用mywc.c计算各种内容,然后把内容返回给客户端,即可实现实验一

运行结果:

1072918-20171119163342890-1884156762.png
1072918-20171119163349671-874362154.png

实验二

任务要求

1.使用多线程实现wc服务器并使用同步互斥机制保证计数正确

2.上方提交代码

3.下方提交测试

4.对比单线程版本的性能,并分析原因

实现步骤

实验二是关于多线程的,这需要在实验一的基础上利用pthread_create()函数把实验一改成多线程,首先用man命令查看多线程函数

1072918-20171119163136624-1413422622.png

利用此函数将第一次的代码改写

运行代码

#### 服务器#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFLEN 1024 #define PORT 6666#define LISTNUM 20 int main() { int sockfd, newfd; struct sockaddr_in s_addr, c_addr; char buf[BUFLEN]; socklen_t len; unsigned int port, listnum; fd_set rfds; struct timeval tv; int retval,maxfd; /*建立socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(errno); }else printf("socket create success!\n"); memset(&s_addr,0,sizeof(s_addr)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(PORT); s_addr.sin_addr.s_addr = htons(INADDR_ANY); /*把地址和端口帮定到套接字上*/ if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){ perror("bind"); exit(errno); }else printf("bind success!\n"); /*侦听本地端口*/ if(listen(sockfd,listnum) == -1){ perror("listen"); exit(errno); }else printf("the server is listening!\n"); while(1){ printf("*****************聊天开始***************\n"); len = sizeof(struct sockaddr); if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){ perror("accept"); exit(errno); }else printf("正在与您聊天的客户端是:%s: %d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port)); while(1){ FD_ZERO(&rfds); FD_SET(0, &rfds); maxfd = 0; FD_SET(newfd, &rfds); /*找出文件描述符集合中最大的文件描述符*/ if(maxfd < newfd) maxfd = newfd; /*设置超时时间*/ tv.tv_sec = 6; tv.tv_usec = 0; /*等待聊天*/ retval = select(maxfd+1, &rfds, NULL, NULL, &tv); if(retval == -1){ printf("select出错,与该客户端连接的程序将退出\n"); break; }else if(retval == 0){ printf("waiting...\n"); continue; }else{ /*用户输入信息了*/ if(FD_ISSET(0, &rfds)){ /******发送消息*******/ memset(buf,0,sizeof(buf)); /*fgets函数:从流中读取BUFLEN-1个字符*/ fgets(buf,BUFLEN,stdin); /*打印发送的消息*/ //fputs(buf,stdout); if(!strncasecmp(buf,"quit",4)){ printf("server 请求终止聊天!\n"); break; } len = send(newfd,buf,strlen(buf),0); if(len > 0) printf("\t消息发送成功:%s\n",buf); else{ printf("消息发送失败!\n"); break; } } /*客户端发来了消息*/ if(FD_ISSET(newfd, &rfds)){ /******接收消息*******/ memset(buf,0,sizeof(buf)); /*fgets函数:从流中读取BUFLEN-1个字符*/ len = recv(newfd,buf,BUFLEN,0); if(len > 0) printf("客户端发来的信息是:%s\n",buf); else{ if(len < 0 ) printf("接受消息失败!\n"); else printf("客户端退出了,聊天终止!\n"); break; } } } } /*关闭聊天的套接字*/ close(newfd); /*是否退出服务器*/ printf("服务器是否退出程序:y->是;n->否? "); bzero(buf, BUFLEN); fgets(buf,BUFLEN, stdin); if(!strncasecmp(buf,"y",1)){ printf("server 退出!\n"); break; } } /*关闭服务器的套接字*/ close(sockfd); return 0; }

客户端

include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFLEN 1024#define PORT 6666int main(int argc, char **argv){ int sockfd; struct sockaddr_in s_addr; socklen_t len; unsigned int port; char buf[BUFLEN]; fd_set rfds; struct timeval tv; int retval, maxfd; /*建立socket*/ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(errno); }else printf("socket create success!\n"); /*设置服务器ip*/ memset(&s_addr,0,sizeof(s_addr)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(PORT); if (inet_aton(argv[1], (struct in_addr *)&s_addr.sin_addr.s_addr) == 0) { perror(argv[1]); exit(errno); } /*开始连接服务器*/ if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1){ perror("connect"); exit(errno); }else printf("conncet success!\n"); while(1){ FD_ZERO(&rfds); FD_SET(0, &rfds); maxfd = 0; FD_SET(sockfd, &rfds); if(maxfd < sockfd) maxfd = sockfd; tv.tv_sec = 6; tv.tv_usec = 0; retval = select(maxfd+1, &rfds, NULL, NULL, &tv); if(retval == -1){ printf("select出错,客户端程序退出\n"); break; }else if(retval == 0){ printf("waiting...\n"); continue; }else{ /*服务器发来了消息*/ if(FD_ISSET(sockfd,&rfds)){ /******接收消息*******/ bzero(buf,BUFLEN); len = recv(sockfd,buf,BUFLEN,0); if(len > 0) printf("服务器发来的消息是:%s\n",buf); else{ if(len < 0 ) printf("接受消息失败!\n"); else printf("服务器退出了,聊天终止!\n"); break; } } /*用户输入信息了,开始处理信息并发送*/ if(FD_ISSET(0, &rfds)){ /******发送消息*******/ bzero(buf,BUFLEN); fgets(buf,BUFLEN,stdin); if(!strncasecmp(buf,"quit",4)){ printf("client 请求终止聊天!\n"); break; } len = send(sockfd,buf,strlen(buf),0); if(len > 0) printf("\t消息发送成功:%s\n",buf); else{ printf("消息发送失败!\n"); break; } } } } /*关闭连接*/ close(sockfd); return 0;}

运行截图

1072918-20171119163448437-1091132493.png

1072918-20171119163505562-1909745700.png
1072918-20171119163514187-1253517262.png

转载于:https://www.cnblogs.com/fengxingck/p/7860211.html

你可能感兴趣的文章
Unsupported major.minor version 52.0
查看>>
面对对象之差异化的网络数据交互方式--单机游戏开发之无缝切换到C/S模式
查看>>
优酷网架构学习笔记
查看>>
把HDFS里的json数据转换成csv格式
查看>>
WEEX-EROS | 集成并使用 bindingx
查看>>
Spring5源码解析-Spring中的异步和计划任务
查看>>
广州牵引力来告诉你学编程先学什么语言好?
查看>>
广州牵引力总结初学者怎样学好UI设计?
查看>>
使用Metrics方法级远程监控Java程序
查看>>
Spring核心系列之Bean的生命周期
查看>>
VasSonic源码之并行加载
查看>>
小程序 LRU 存储设计
查看>>
Android 多线程之阻塞队列
查看>>
[译] 关于 Angular 依赖注入你需要知道的
查看>>
Haskell 在 macOS 下的环境搭建
查看>>
适配mpvue平台的的微信小程序日历组件mpvue-calendar
查看>>
【Linux学习】 Redis常用的一些指令
查看>>
Spring Cloud 中使用Feign解决参数注解无法继承的问题
查看>>
数据迁移方案 + Elasticsearch在综合搜索列表实现
查看>>
干货 | 分分钟教你用Python创建一个区块链
查看>>