2017-2018-1 20155323 《信息安全系统设计基础》第8周学习总结
2017-2018-1 20155323 《信息安全系统设计基础》第8周学习总结
3.基于socket 使用教材的csapp.h csapp.c,实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端
服务器响应消息格式是
“
客户端IP:XXXX
服务器实现者学号:XXXXXXXX
当前时间: XX:XX:XX
”
上方提交代码
提交一个客户端至少查询三次时间的截图测试截图
提交至少两个客户端查询时间的截图测试截图
- 实验过程:
编写服务器代码:
#include<netinet/in.h> // sockaddr_in
#include<sys/types.h> // socket
#include<sys/socket.h> // socket
#include<stdio.h> // printf
#include<stdlib.h> // exit
#include<string.h> // bzero
#include<time.h>#define SERVER_PORT 13323
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main(void)
{ // 声明并初始化一个服务器端的socket地址结构 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(SERVER_PORT); // 创建socket,若成功,返回socket描述符 int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0); if(server_socket_fd < 0) { perror("Create Socket Failed:"); exit(1); } int opt = 1; setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 绑定socket和socket地址结构 if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)))) { perror("Server Bind Failed:"); exit(1); } // socket监听 if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE))) { perror("Server Listen Failed:"); exit(1); } while(1) { // 定义客户端的socket地址结构 struct sockaddr_in client_addr; socklen_t client_addr_length = sizeof(client_addr); // 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信 // accept函数会把连接到的客户端信息写到client_addr中 int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length); if(new_server_socket_fd < 0) { perror("Server Accept Failed:"); break; } char buffer1[BUFFER_SIZE]; char buffer2[BUFFER_SIZE];bzero(buffer1, BUFFER_SIZE); bzero(buffer2, BUFFER_SIZE); time_t ticks;ticks = time(NULL);recv(new_server_socket_fd, buffer1, BUFFER_SIZE, 0);recv(new_server_socket_fd, buffer2, BUFFER_SIZE, 0);printf("客户端IP:%s\n服务器实现者学号:%s\n当前时间:%.24s\r\n", buffer1,buffer2,ctime(&ticks));// 关闭与客户端的连接
} // 关闭监听用的socket close(server_socket_fd); return 0;}
注意实验要求是要一个客户端至少查询三次时间并且要可以同时打开两个客户端,所以close语句必须要在循环外。
然后是编写客户端代码:
#include<netinet/in.h> // sockaddr_in
#include<sys/types.h> // socket
#include<sys/socket.h> // socket
#include<stdio.h> // printf
#include<stdlib.h> // exit
#include<string.h> // bzero #define SERVER_PORT 13323
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main()
{ // 声明并初始化一个客户端的socket地址结构 struct sockaddr_in client_addr; bzero(&client_addr, sizeof(client_addr)); client_addr.sin_family = AF_INET; client_addr.sin_addr.s_addr = htons(INADDR_ANY); client_addr.sin_port = htons(0); // 创建socket,若成功,返回socket描述符 int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0); if(client_socket_fd < 0) { perror("Create Socket Failed:"); exit(1); } // 绑定客户端的socket和客户端的socket地址结构 非必需 if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr)))) { perror("Client Bind Failed:"); exit(1); } // 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接 struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0) { perror("Server IP Address Error:"); exit(1); } server_addr.sin_port = htons(SERVER_PORT); socklen_t server_addr_length = sizeof(server_addr); // 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接 if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0) { perror("Can Not Connect To Server IP:"); exit(0); } char buffer[BUFFER_SIZE]; bzero(buffer, BUFFER_SIZE); strcpy(buffer,"127.0.0.1");// 向服务器发送buffer中的数据 if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0) { perror("Send Failed:"); exit(1); }bzero(buffer, BUFFER_SIZE); strcpy(buffer,"20155323");if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0) { perror("Send Failed:"); exit(1); } close(client_socket_fd); return 0;
}
实验截图:
教材学习内容总结
并发编程
基于进程的并发编程
- 常用函数:
fork
exec
waitpid
- 需要说明的内容:
必须要包括一个SIGCHLD处理程序来回收僵死子进程的资源。
父进程需要关闭它的已连接描述符的拷贝以避免内存泄漏。
父子进程之间共享文件表,但是不共享用户地址空间。
进程的优劣
- 注意:进程的模型:共享文件表,但不是共享用户地址空间。
- 优点:一个进程不可能不小心覆盖两一个进程的虚拟存储器。
- 缺点:独立的地址空间使得进程共享状态信息变得更加困难。进程控制和IPC的开销很高。
基于I/O多路复用的并发编程
- 只允许对描述符做的三件事:
1.分配他们。
2.将一个此种类型的变量赋值给另一个变量。
3.用FD_ZERO、FD_SET、FD_CLR和FD_ISSET宏指令来修改和检查它们。
基于I/O多路复用的并发事件驱动服务器
状态机就是一组状态、输入事件和转移,转移就是将状态和输入时间映射到状态,自循环是同一输入和输出状态之间的转移。
I/O多路复用技术的优势
- 优点:
(1)比基于进程的设计给了程序员更多的对程序行为的控制
(2)运行在单一进程上下文中,因此,每个逻辑流都能访问该进程的全部地址空间,使得流之间共享数据变得很容易。
(3)不需要进程上下文切换来调度新的流。
- 缺点:
(1)编码复杂
(2)不能充分利用多核处理器
粒度:每个逻辑流每个时间片执行的指令数量。并发粒度就是读一个完整的文本行所需要的指令数量。
基于线程的并发编程
- 这是前两种创建并发逻辑流方法的混合。
Posix线程
- 线程的代码和本地数据被封装在一个线程例程中。每一个线程例程都以一个通用指针作为输入,并返回一个通用指针。
创建线程
- 通过调用
pthread create
函数创建一个新的线程,并带着一个输入变量arg,在新线程的上下文中运行线程例程f。新线程可以通过调用pthread _self函数来获得自己的线程ID。
终止线程
-一个线程的终止方式:
(1)当顶层的线程例程返回时,线程会隐式的终止;
(2)通过调用
pthread _exit
函数,线程会显示地终止。如果主线程调用pthread _exit
,它会等待所有其他对等线程终止,然后再终止主线程和整个进程。
回收已终止线程的资源
- 通过调用
pthread _join
函数等待其他线程终止,回收已终止线程占用的所有存储器资源。pthread _join
函数只能等待一个指定的线程终止。
分离线程
- 在任何一个时间点上,线程是可结合的,或是分离的。一个可结合的线程能够被其他线程收回其资源和杀死;一个可分离的线程是不能被其他线程回收或杀死的。它的存储器资源在它终止时有系统自动释放。
- 通过调用
pthread _detach
函数被分离。
初始化线程
- 通过调用
pthread_once
函数初始化与线程例程相关的状态。
多线程程序中的共享变量
- 一个变量是共享的,当且仅当多个线程引用这个变量的某个实例。
线程存储器模型
- 寄存器从不共享,虚拟存储器总是共享的。
将变量映射到存储器
- 全局变量:全局变量是定义在函数之外的变量。运行时虚拟内存的读/写区域只包含每个全局变量的一个实例,任何线程都可以引用。
- 本地自动变量:本地自动变量是定义在函数内部但没有static属性的变量。运行时每个线程的栈都包含它自己的所有本地自动变量的实例。
- 本地静态变量:本地静态变量是定义在函数内部并有static属性的变量。和全局变量一样运行时虚拟内存的读/写区域只包含每个本地静态变量的一个实例。
教材学习中的问题和解决过程
问题1:如何判断线程是否安全
解答:
线程安全:当且仅当被多个并发线程反复地调用时,它会一直产生正确的结果。
线程不安全:如果一个函数不是线程安全的,就是线程不安全的。
代码托管
结对及互评
本周结对学习情况
20155314刘子健
- 结对学习内容
第十二章
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 50/50 | 1/1 | 5/5 | |
第二周 | 100/100 | 1/2 | 5/10 | |
第三周 | 100/200 | 1/3 | 5/15 | |
第四周 | 100/300 | 1/4 | 5/20 | |
第五周 | 100/400 | 1/5 | 5/25 | |
第六周 | 100/500 | 1/6 | 5/30 | |
第七周 | 100/600 | 1/7 | 5/35 |
转载于:https://www.cnblogs.com/fixedl/p/7822985.html
2017-2018-1 20155323 《信息安全系统设计基础》第8周学习总结相关推荐
- # 2017-2018-1 20155224 《信息安全系统设计基础》第九周学习总结
2017-2018-1 20155224 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 存储器 随机访问存储器(RAM): 静态RAM:用来作为高速缓存存储器,每个位存储在一个 ...
- 2018-2019-1 20165206 《信息安全系统设计基础》第九周学习总结
- 2018-2019-1 20165206 <信息安全系统设计基础>第九周学习总结 - 教材学习内容总结 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组.每个字节都有一 ...
- 20135203齐岳 信息安全系统设计基础第十三周学习总结
20135203齐岳 信息安全系统设计基础第十三周学习总结 学习计时:8/9共小时(计划/实际) 读书:4/5 代码:1/1 作业:1/1 博客:2/2 第十二章 并发编程 一.学习目标 掌握三种并发 ...
- # 20155337 2017-2018-1 《信息安全系统设计基础》第一周学习总结
20155337 2017-2018-1 <信息安全系统设计基础>第一周学习总结 教材学习内容总结 1.1信息就是位+上下文 hello.c程序是以字节序列的方式储存在文件中的.每个字节都 ...
- 20135219洪韶武——信息安全系统设计基础第五周学习总结
信息安全系统设计基础第五周学习总结 学习任务:教材第四章[处理器体系结构] 学习时间:10小时 一.教材知识点梳理[4.1-4.3] 1.ISA[指令集体系结构] 一个处理器支持的指令和指令的字节级 ...
- 20145227《信息安全系统设计基础》第一周学习总结
20145227<信息安全系统设计基础>第一周学习总结 学习内容总结 Linux是一个操作系统.如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命 ...
- 2018-2019 20165203 《信息安全系统设计基础》第一周学习总结
2018-2019-1 20165203 <信息安全系统设计基础>第一周学习总结 教材学习内容总结 编译:gcc [选项] [文件名] 选项参数表 参数 对应功能 -E 仅执行编译预处理 ...
- 2018-2019-1 20165221 《信息安全系统设计基础》第一周学习总结
2018-2019-1 20165221 <信息安全系统设计基础>第一周学习总结 教材学习总结 有关vim 打开方式:vim [文件名] 按i会进入insert模式,可以对代码进行编辑 按 ...
- 2017-2018-1 20155209 《信息安全系统设计基础》第一周学习总结
2017-2018-1 20155209 <信息安全系统设计基础>第一周学习总结 教材学习内容总结 计算机系统就是由可以看到的硬件和系统内的软件组成的,然后用来运行应用程序. 我们平时使用 ...
- 20145307《信息安全系统设计基础》第二周学习总结
20145307<信息安全系统设计基础>第二周学习总结 教材学习内容总结 vim编辑器 Vim的6种基本模式:Vim具有6种基本模式和5种派生模式普通模式(Normal mode) Vim ...
最新文章
- 【第13周复盘】小朋友们也开始卷了
- [问题解决] Python中 == 与 is 的区别
- nacos config基本使用
- SUM and REPLACE
- 用ionic快速开发hybird App(已附源码,在下面+总结见解)
- 爬虫基本库request使用—爬取猫眼电影信息
- extjs4.2 前端读取对象的方法
- 数字图像处理--图像旋转变换的推导
- Power BI Desktop中的“提问”功能
- asp.net 配置 X-Frame-Options
- mysql 键 索引_五、MySQL索引和键
- mysql自动跑sql发邮件_SQL server 表数据改变触发发送邮件的方法
- Java高并发编程实战5,异步注解@Async自定义线程池
- 涂上你的脸! 如何创建自定义Photoshop笔刷
- 使用python bloomfilter实现大文本去重
- **MA2灯光控台的TIMECODE 说明**
- 历史_美股和美债的联动关系
- linux改d5000默认路径,linux相关指令和d5000基础操作.pdf
- ECU软件开发介绍篇
- UVC 摄像头驱动(二)描述符分析