20155206赵飞 基于《Arm试验箱的国密算法应用》课程设计个人报告

20155206赵飞 基于《Arm试验箱的国密算法应用》课程设计个人报告

课程设计中承担的任务

完成试验箱测试功能1,2,3

、 1:LED闪烁实验
一、实验目的
 学习GPIO原理
 掌握Z32安全模块驱动LED的工作原理
二、实验内容
学习GPIO原理,阅读《ARM cortex-m0权威手册》(详见目录Z32开发指南\3.参考资料),参考Z32HUA_DEMO工程函数库(详见Z32开发指南\2.软件资料),通过设置GPIO0来控制核心板上L2灯的亮灭。
三、预备知识
 有C语言基础知识
 掌握Keil uVision4的开发环境
 掌握Z32应用程序的框架结构
四、实验设备及工具
硬件:信息安全系统设计与应用试验平台、USB转9针串口线、标准双头USB连接线、配有Win7及以上系统的PC机,硬盘10G以上。
软件:Keil uVision4开发环境
五、实验原理
Z32内部支持33个可复用 GPIO 接口,所有IO都支持上、下拉可配置;中断都支持上升沿触发、下降沿触发或双沿触发配置,唤醒 IO 支持高低电平触发;IO 驱动能力不小于4mA,其中2个IO驱动能力不少于12mA。
General Purpose Input Output (通用输入/输出)简称为GPIO,或总线扩展器,人们利用工业标准I2C、SMBus或SPI接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。
GPIO端口的每个位可以由软件分别配置成多种模式:
 输入浮空
 输入上拉
 输入下拉
 模拟输入
 开漏输出
 推挽式输出
 推挽式复用功能
 开漏复用功能
GPIO管脚工作模式有3种比较常用:高阻输入、推挽输出、开漏输出
1. 高阻输入(Input)

图1 GPIO高阻输入模式结构示意图
为减少信息传输线的数目,大多数计算机中的信息传输线采用总线形式,即凡要传输的同类信息都在同一组传输线,且信息是分时传送的。在计算机中一般有三组总线,即数据总线、地址总线和控制总线。为防止信息相互干扰,要求凡挂到总线上的寄存器或存储器等,它的输入输出端不仅能呈现0、1两个信息状态,而且还应能呈现第三个状态----高阻抗状态,即此时好像它们的输出被开关断开,对总线状态不起作用,此时总线可由其他器件占用。三态缓冲器即可实现上述功能,它除具有输入输出端之外,还有一控制端。
如图1.1所示,为GPIO管脚在高阻输入模式下的等效结构示意图。这是一个管脚的情况,其它管脚的结构也是同样的。输入模式的结构比较简单,就是一个带有施密特触发输入(Schmitt-triggered input)的三态缓冲器(U1),并具有很高的输入等效阻抗。施密特触发输入的作用是能将缓慢变化的或者是畸变的输入脉冲信号整形成比较理想的矩形脉冲信号。执行GPIO管脚读操作时,在读脉冲(Read Pulse)的作用下会把管脚(Pin)的当前电平状态读到内部总线上(Internal Bus)。在不执行读操作时,外部管脚与内部总线之间是隔离的。
2. 推挽输出(Output)

图2 GPIO推挽输出模式结构示意图
推挽输出原理:在功率放大器电路中大量采用推挽放大器电路,这种电路中用两只三极管构成一级放大器电路,两只三极管分别放大输入信号的正半周和负半周,即用一只三极管放大信号的正半周,用另一只三极管放大信号的负半周,两只三极管输出的半周信号在放大器负载上合并后得到一个完整周期的输出信号。
推挽放大器电路中,一只三极管工作在导通、放大状态时,另一只三极管处于截止状态,当输入信号变化到另一个半周后,原先导通、放大的三极管进入截止,而原先截止的三极管进入导通、放大状态,两只三极管在不断地交替导通放大和截止变化,所以称为推挽放大器。
如图1.2所示,为GPIO管脚在推挽输出模式下的等效结构示意图。U1是输出锁存器,执行GPIO管脚写操作时,在写脉冲(Write Pulse)的作用下,数据被锁存到Q和/Q。T1和T2构成CMOS反相器,T1导通或T2导通时都表现出较低的阻抗,但T1和T2不会同时导通或同时关闭,最后形成的是推挽输出。在推挽输出模式下,GPIO还具有回读功能,实现回读功能的是一个简单的三态门U2。注意:执行回读功能时,读到的是管脚的输出锁存状态,而不是外部管脚Pin的状态。
3. 开漏输出(OutputOD)

图3 GPIO开漏输出结构示意图
如图1.3所示,为GPIO管脚在开漏输出模式下的等效结构示意图。开漏输出和推挽输出相比结构基本相同,但只有下拉晶体管T1而没有上拉晶体管。同样,T1实际上也是多组可编程选择的晶体管。开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到GND(有一定内阻)。回读功能:读到的仍是输出锁存器的状态,而不是外部管脚Pin的状态。因此开漏输出模式是不能用来输入的。
开漏输出结构没有内部上拉,因此在实际应用时通常都要外接合适的上拉电阻(通常采用4.7~10kΩ)。开漏输出能够方便地实现“线与”逻辑功能,即多个开漏的管脚可以直接并在一起(不需要缓冲隔离)使用,并统一外接一个合适的上拉电阻,就自然形成“逻辑与”关系。开漏输出的另一种用途是能够方便地实现不同逻辑电平之间的转换(如3.3V到5V之间),只需外接一个上拉电阻,而不需要额外的转换电路。典型的应用例子就是基于开漏电气连接的I2C总线。
六、程序分析
本此实验例程的详细程序请打开“Z32开发指南\实验1-LED闪烁”目录文件夹下的工程文件,下面我们对程序的主要部分做一下简单的分析。
打开LED闪烁实验工程文件,如图所示:

在user组和driver组下分别双击Main.c和Gpio.c,就可以看到程序的源代码。
七、实验步骤
1、打开“Z32开发指南\实验1-LED闪烁”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验1的程序就下载进Z32的实验板上了。
八、实验现象
实验1的内容是对LED灯的操作,我们关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:Z32核心板上L2灯开始闪烁。

、2:UART发送与中断接收实验
一、实验目的
 学习串口通信原理
 掌握SP3232芯片的使用方法
 掌握Z32的串行口工作原理
二、实验内容
学习串口通信原理,熟练Z32系统硬件的UART使用方法,编程实现串口通信的基本收发功能,利用上位机上的串口调试助手观测发送和收到的数据。
三、预备知识
 C语言基础知识
 掌握Keil uVision4的开发环境
 Z32应用程序的框架结构
四、实验设备及工具
硬件:信息安全系统设计与应用试验平台、USB转9针串口线、标准双头USB连接线、配有Win7及以上系统的PC机,硬盘10G以上。
软件:Keil uVision4开发环境
五、实验原理
1、串行接口标准
RS-232接口符合美国电子工业联盟(EIA)制定的串行数据通信的接口标准,原始编号全称是EIA-RS-232(简称232,RS232)。目前RS-232是PC机与通信工业中应用最广泛的一种串行接口。RS-232被定义为一种在低速率串行通讯中增加通讯距离的单端标准。RS-232采取不平衡传输方式,即所谓单端通讯。RS232接口的通讯距离小于15 m,传输速率小于20 kb/s。RS232标准是按负逻辑定义的,它的“1”电平在-5~-15 V之间,“0”电平在+5~+15 V之间。

在RS-232的通讯标准中是以一个25针的接口来定义的,并在早期的计算机如PC或XT机型上广泛使用,但在AT机以后的机型上,实际均采用了9针的简化版本应用,现在所说的232通讯均默认为9针的接口。图一显示了9针通讯的接口管脚名称,以下是各管脚的说明:
表1 9针串口引脚说明
旧制JIS名称 新制JIS名称 全称 说明
FG SG Frame Ground 连到机器的接地线
TXD SD Transmitted Data 数据输出线
RXD RD Received Data 数据输入线
RTS RS Request to Send 要求发送数据
CTS CS Clear to Send 回应对方发送的RTS的发送许可,告诉对方可以发送
DSR DR Data Set Ready 告知本机在待命状态
DTR ER Data Terminal Ready 告知数据终端处于待命状态
CD CD Carrier Detect 载波检出,用以确认是否收到Modem的载波
SG SG Signal Ground 信号线的接地线(严格的说是信号线的零标准线)
现在通常计算机均配有这种标准的232接口,通常这种接口用于联接鼠标、MODEM或打印机等外部设备。实际应用中,电子工程师在设计计算机与外围设备的通信时,通常在9针的基础再进行简化,只用其中的2、3、5三个管脚进行通信。这三个管脚分别是接收线、发送线和地线,在一般情况下即可满足通讯的要求

图2 计算机和外部通讯的接线方法
值得注意的是,2、3两脚是交叉互联的,这很容易理解,因为一个设备的发送线必须联接到另外一台设备的接收线上,反之亦然。
对于没有配有这种标准的232接口的PC机,但是有USB接口,我们需要使用USB转9针串口线将PC机和另外一台串口设备连接起来,其中USB转9针串口线起到电平转换和协议转换的作用。

六、程序分析
本此实验例程的详细程序请打开“Z32开发指南\实验2-UART发送与中断接收”目录文件夹下的工程文件,下面我们对程序的主要部分做一下简单的分析。
打开LED闪烁实验工程文件,如图所示:

在user组和driver组下分别双击Main.c和Uart.c,就可以看到程序的源代码。
七、实验步骤
1、打开“Z32开发指南\实验2-UART发送与中断接收”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验2的程序就下载进Z32的实验板上了。
八、实验现象
实验2使用串口调试助手(sscom)来观察串口通信收发的数据。
我们用9针串口线将Z32模块的串口与电脑USB接口连接。

首先在电脑上打开串口助手,选择对应的串口号,设置波特率为115200,偶校验(Even),选中“发送新行”,然后打开串口。
关闭Z32电源开关,再打开,程序自动运行,可以在串口调试助手看到如下实验现象:显示“A Welcome to Z32HUA! 1234567890 0xAA”,证明PC机串口已经接收到Z32串口发送来的信息。
我们在串口调试助手的字符串输入框输入字符串“zxm zxm zxm abc”,然后点击发送按钮。
这时,可以看到串口调试助手接收到我们发送输入的字符串“zxm zxm zxm abc”,并显示在串口助手上。

、3:12864液晶屏串行显示实验
一、实验目的
 学习12864液晶屏原理
 掌握Z32的GPIO工作原理
 掌握12864液晶屏的使用方法
二、实验内容
学习GPIO原理,阅读《ARM cortex-m0权威手册》,参考Z32HUA_DEMO工程函数库(详见软件资料),通过设置通过GPIO1,GPIO2,GPIO3串行通信控制液晶屏,实现字符显示功能。
三、预备知识
 有C语言基础知识
 掌握Keil uVision4的开发环境
 掌握Z32应用程序的框架结构
四、实验设备及工具
硬件:信息安全系统设计与应用试验平台、USB转9针串口线、标准双头USB连接线、配有Win7及以上系统的PC机,硬盘10G以上。
软件:Keil uVision4开发环境
五、实验原理
(一)、概述
12864是一种图形点阵液晶显示器。它主要采用动态驱动原理由行驱动—控制器和列驱动器两部分组成了128(列)×64(行)的全点阵液晶显示。此显示器采用了COB的软封装方式,通过导电橡胶和压框连接LCD,使其寿命长,连接可靠。
(二)、特性
1.工作电压为+5V±10% ,可自带驱动LCD所需的负电压。
2.全屏幕点阵,点阵数为128(列)×64(行),可显示8(/行)×4(行)个(16×16点阵)汉字,也可完成图形,字符的显示。
3.与CPU接口采用5条位控制总线和8位并行数据总线输入输出,适配M6800系列时序。
4.内部有显示数据锁存器。
5.简单的操作指令,显示开关设置,显示起始行设置,地址指针设置和数据读/写等指令。

1)显示数据 RAM(DDRAM)
DDRAM(64×8×8 bits)是存储图形显示数据的。此 RAM 的每一位数据对应显示面板上一个点的显示(数据为 H)与不显示(数据为 L)。DDRAM 的地址与显示位置关系对照图(见附录一)
2)I/O 缓冲器(DB0~DB7)
I/O 缓冲器为双向三态数据缓冲器。是 LCM(液晶显示模块)内部总线与 MPU 总线的结合部。其作用是将两个不同时钟下工作的系统连接起来,实现通讯。I/O 缓冲器在片选信号/CS有效状态下,I/O 缓冲器开放,实现 LCM(液晶显示模块)与 MPU 之间的数据传递。当片选信号为无效状态时,I/O 缓冲器将中断 LCM(液晶显示模块)内部总线与 MPU 数据总线的联系,对外总线呈高阻状态,从而不影响 MPU 的其他数据操作功能。
3)输入寄存器
输入寄存器用于接收在 MPU 运行速度下传送给 LCM(液晶显示模块)的数据并将其锁存在输入寄存器内,其输出将在 LCM(液晶显示模块)内部工作时钟的运作下将数据写入指令寄存器或显示存储器内。
4)输出寄存器
输出寄存器用于暂存从显示存储器读出的数据,在 MPU 读操作时,输出寄存器将当前锁
存的数据通过 I/O 缓冲器送入 MPU 数据总线上。
5)指令寄存器
指令寄存器用于接收 MPU 发来的指令代码,通过译码将指令代码置入相关的寄存器或触
发器内。
6)状态字寄存器
状态字寄存器是 LCM(液晶显示模块)与 MPU 通讯时唯一的“握手”信号。状态字寄存器向 MPU 表示了 LCM(液晶显示模块)当前的工作状态。尤其是状态字中的“忙”标志位是MPU 在每次对 LCM(液晶显示模块)访问时必须要读出判别的状态位。当处于“忙”标志位时,I/O 缓冲器被封锁,此时 MPU 对 LCM(液晶显示模块)的任何操作(除读状态字操作外)都将是无效的。
7)X 地址寄存器
X 地址寄存器是一个三位页地址寄存器,其输出控制着 DDRAM 中 8 个页面的选择,也是控制着数据传输通道的八选一选择器。X 地址寄存器可以由 MPU 以指令形式设置。X 地址寄存器没有自动修改功能,所以要想转换页面需要重新设置 X 地址寄存器的内容。
8)Y 地址计数器
Y 地址计数器是一个 6 位循环加一计数器。它管理某一页面上的 64 个单元。Y 地址计数器可以由 MPU 以指令形式设置,它和页地址指针结合唯一选通显示存储器的一个单元,Y 地址计数器具有自动加一功能。在显示存储器读/写操作后 Y 地址计数将自动加一。当计数器加至 3FH 后循环归零再继续加一。
9)Z 地址计数器
Z 地址计数器是一个 6 位地址计数器,用于确定当前显示行的扫描地址。Z 地址计数器具有自动加一功能。它与行驱动器的行扫描输出同步,选择相应的列驱动的数据输出。
10)显示起始行寄存器
显示起始行寄存器是一个 6 位寄存器,它规定了显示存储器所对应显示屏上第一行的行号。该行的数据将作为显示屏上第一行显示状态的控制信号。
11)显示开/关触发器
显示开/关触发器的作用就是控制显示驱动输出的电平以控制显示屏的开关。在触发器输出为“关”电平时,显示数据锁存器的输入被封锁并将输出置“0”,从而使显示驱动输出全部为非选择波形,显示屏呈不显示状态。在触发器输出为“开”电平时,显示数据锁存器被控制,显示驱动输出受显示驱动数据总线上数据控制,显示屏将呈显示状态。
12)复位端/RES
复位端/RES 用于在 LCM(液晶显示模块)上电时或需要时实现硬件电路对 LCM(液晶显示模块)的复位。该复位功能将实现:
 设置显示状态为关显示状态
 显示起始寄存器清零。显示 RAM 第一行对应显示屏上的第一行。
 在复位期间状态字中 RESET 位置“1”。 初始化条件:

六、程序分析
本实验例程的详细程序请打开“Z32开发指南\实验3 12864液晶屏串行显示”文件夹下的工程文件,下面我们对程序的主要部分做一下简单的分析。
打开12864液晶屏串行显示实验工程文件,如图所示:

然后在user组下分别双击Main.c和LCD.c可以看到主函数代码和12864液晶屏的函数代码
七、实验步骤
1、打开“Z32开发指南\实验3-12864液晶屏串行显示”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验3的程序就下载进Z32的实验板上了。

八、实验现象
实验3的内容是LCD12864液晶屏的显示操作。
关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:屏幕上依次显示以下字符:
“欢迎使用Z32HUA!
LCD12864液晶测试
1.2.3.4.5.6.7.8.
A.B.C.D.E.F.G.H.”
其中行与行之间显示的间隔时间约为1.8s,四行字符全部显示完成后清屏幕,重新循环显示。

完成SM2加密实验

一、实验目的
 学习SM2加解密算法原理,掌握SM2加、解密算法用法
二、实验内容
学习SM1加密原理,阅读《ARM cortex-m0权威手册》和《Z32HUA国密算法库用户手册》(详见目录Z32开发指南\3.参考资料),参考Z32HUA_DEMO工程函数库(详见Z32开发指南\2.软件资料),调用SM2加解密函数,实现对数据加解密操作。
三、预备知识
 有C语言基础知识
 掌握Keil uVision4的开发环境
 掌握Z32应用程序的框架结构
 掌握国密SM2加解密算法函数的用法
四、实验设备及工具
硬件:信息安全系统设计与应用试验平台、USB转9针串口线、标准双头USB连接线、配有Win7及以上系统的PC机,硬盘10G以上。
软件:Keil uVision4开发环境、串口调试助手SSCOM4.2。
五、实验原理
国密SM2是非对称密码算法,是基于ECC算法的非对称算法。SM2算法就是ECC椭圆曲线密码机制,但在签名、密钥交换方面不同于ECDSA、ECDH等国际标准,而是采取了更为安全的机制。另外,SM2推荐了一条256位的曲线作为标准曲线。
国密SM2算法标准包括4个部分,第1部分为总则,主要介绍了ECC基本的算法描述,包括素数域和二元扩域两种算法描述,第2部分为数字签名算法,这个算法不同于ECDSA算法,其计算量大,也比ECDSA复杂些,也许这样会更安全吧,第3部分为密钥交换协议,与ECDH功能相同,但复杂性高,计算量加大,第4部分为公钥加密算法,使用ECC公钥进行加密和ECC私钥进行加密算法,其实现上是在ECDH上分散出流密钥,之后与明文或者是密文进行异或运算,并没有采用第3部分的密钥交换协议产生的密钥。对于SM2算法的总体感觉,应该是国家发明,其计算上比国际上公布的ECC算法复杂,相对来说算法速度可能慢,但可能是更安全一点。
SM2标准还公布了一条建议的256位的ECC曲线,但没有在国际上被公认。SM2算法是好,但要使用,又有很多障碍,就是统一的国际标识与互认,如算法没有OID标识,曲线也没有公认OID标识,这在通用上就大打折扣了,这一点需要考虑的。
六、程序分析
本此实验例程的详细程序请打开“Z32开发指南\实验9-SM2”目录文件夹下的工程文件,下面我们对程序的主要部分做一下简单的分析。
打开SM2加解密实验工程文件,如图所示:

2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
图5 Z32下载工具成功连接图
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验8的程序就下载进Z32的实验板上了。
八、实验现象
实验9的内容是SM2加解密实验。本实验使用Z32内置函数库实现加解密算法。
我们用9针串口线将Z32模块的串口与电脑USB接口连接。
首先在电脑上打开串口助手,选择对应的串口号,设置波特率为115200,偶校验(Even),然后打开串口。
关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:12864屏幕上显示“SM2实验!请看串口助手”。
在字符串输入框输入数据“zxm zxm abc”,点击发送。
输入字符串“zxm zxm abc”发送,字符串显示在串口调试助手上,如图。
按下矩阵键盘“A”键,串口调试助手显示数据“输入的数据为:abc”,并提示“按A键进行加密”。
按矩阵键盘上“A”键,加密后的数据显示在串口调试助手上
再按“A”键,进行解密,解密后的数据显示在串口调试助手上。

完成客户端与服务器通讯的代码

从去年的课程中找到了完成过的代码,直接拿来使用
、 我实现client
、client.c
`#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])  
{  
    int client_sockfd;  
    int len;  
    struct sockaddr_in remote_addr; //服务器端网络地址结构体  
    char buf[BUFSIZ];  //数据传送的缓冲区  
    memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零  
    remote_addr.sin_family=AF_INET; //设置为IP通信  
    remote_addr.sin_addr.s_addr=inet_addr("127.0.0.2");//服务器IP地址  
    remote_addr.sin_port=htons(8000); //服务器端口号  
      
    /*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/  
    if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)  
    {  
        perror("socket");  
        return 1;  
    }  
      
    /*将套接字绑定到服务器的网络地址上*/  
    if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)  
    {  
        perror("connect");  
        return 1;  
    }  
    printf("connected to server\n 客户端IP127.0.0.305\n 服务器实现者学号20155206\n 当前时间2018.5.26\n");  
    len=recv(client_sockfd,buf,BUFSIZ,0);//接收服务器端信息  
         buf[len]='\0';  
    printf("%s",buf); //打印服务器端信息  
      
    /*循环的发送接收信息并打印接收信息--recv返回接收到的字节数,send返回发送的字节数*/  
    while(1)  
    {  
        printf("Enter string to send:");  
        scanf("%s",buf);  
        if(!strcmp(buf,"quit"))  
            break;  
        len=send(client_sockfd,buf,strlen(buf),0);  
        len=recv(client_sockfd,buf,BUFSIZ,0);  
        buf[len]='\0';  
        printf("received:%s/n",buf);  
    }  
    close(client_sockfd);//关闭套接字  
         return 0;  
}  `

、 server.c
`#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])  
{  
    int server_sockfd;//服务器端套接字  
    int client_sockfd;//客户端套接字  
    int len;  
    struct sockaddr_in my_addr;   //服务器网络地址结构体  
    struct sockaddr_in remote_addr; //客户端网络地址结构体  
    int sin_size;  
    char buf[BUFSIZ];  //数据传送的缓冲区  
    memset(&my_addr,0,sizeof(my_addr)); //数据初始化--清零  
    my_addr.sin_family=AF_INET; //设置为IP通信  
    my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上  
    my_addr.sin_port=htons(8000); //服务器端口号  
      
    /*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/  
    if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)  
    {    
        perror("socket");  
        return 1;  
    }  
   
        /*将套接字绑定到服务器的网络地址上*/  
    if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)  
    {  
        perror("bind");  
        return 1;  
    }  
      
    /*监听连接请求--监听队列长度为5*/  
    listen(server_sockfd,5);  
      
    sin_size=sizeof(struct sockaddr_in);  
      
    /*等待客户端连接请求到达*/  
    if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)  
    {  
        perror("accept");  
        return 1;  
    }  
    printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr));  
    len=send(client_sockfd,"Welcome to my server\n 客户端IP127.0.0.3\n 服务器实现者学号20155206\n 当前时间2018.5.26\n",21,0);//发送欢迎信息  
      
    /*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/  
    while((len=recv(client_sockfd,buf,BUFSIZ,0))>0) 
    {  
        buf[len]='\0';  
        printf("%s\n",buf);  
        if(send(client_sockfd,buf,len,0)<0)  
        {  
            perror("write");  
            return 1;  
        }  
    }  
    close(client_sockfd);  
    close(server_sockfd);  
        return 0;  
} `

实验中遇到的问题

  **本次实验在小组三人的共同努力下完成,但是试验箱出现问题,两个实验模块不能同时使用,在同时打开使用时下载进去的代码总有几段是无法运行的,致使实验目前无法继续进行下去;同时,今天(2018.6.3)小组内检查实验完成情况时,在用超级终端与试验箱连接时总会不停的自动断开,然后再次自动连接,这个情况在上次是没有遇到的,目前没有解决。**

posted on 2018-06-03 20:48  赵飞111  阅读(282)  评论(0编辑  收藏  举报