2.3 模块划分 系统结构图如下: 主模块 图2.1聊天模块划分图 2.4 模块调用关系 模块在整体框架中的位置如下图: 图2.2 模块位置关系图 2.5 系统总流程图 Socket 编程几乎是采用的 模式,该模式是基于局域网内进行通信的基础架构,它可以使用任何的通信协议,并且在通信的过程中能充分发挥客户端的处 理能力,使客户端响应速度加快。所以,该系统总体采用C/S 模式。 传输文件未注册用户入口 已注册用户入口 登录 文件加密 私聊 群聊 聊天信息保存文件传输 图2.3系统总流程图 2.6 文件信息安全 每天网络中都要进行大量的数据传输,如果对于这些数据的保密措施没有做 好,那么将对个人及企业带来很大的麻烦,因此信息安全问题也越来越受到人们 开始 打开服务端,处于监听状态 客户端登陆 是否注册 注册 是否加密解密 接收正确数据 信息保存文件关闭交流 关闭客户端 关闭服务端 的关注,人们希望自己在网络上传输的信息不能被别人查看,特别是一些具有重要资料的文件内容。信息的安全关系到人们的利益,所以对文件的内容进行保护 是十分重要的。而对文件内容保护的关键技术就是将文件内容在网络传输中进行 加密,然后解密。 这次对数据的加密,采用的是DES 加密算法。DES 算法是一种对称算法,采用 的是分组数据加密技术,该算法速度快,且能对大量数据进行加密。其DES 计中的大概原理是,当发送文件客户端发送文件时,先将文件的数据进行加密,然后通过socket 套接字发送到接收端,接收端接收到文件,将接收到的文件加密 数据进行解密,如果加密密钥和解密密钥完全相同,接收端就能接收发送过来的 正确数据,否则就是错误数据。当然这里只是局域网内简单的文件数据加密,在 现实生活中各种加密遍布生活的每一个角落,比如现在很热点的无线和无线云等 都需要各种加密措施保护数据传输。基于这种趋势,加密算法在以后的网络发展 中的地位将会一步步的提升。 linux网络编程 3.1 socket 概念及功能 (1)概念:我们把socket 直接翻译过来的意思就是插座,听起来挺古怪的,但是 它的作用就类似于这个插座的作用。作为了解socket 的人都有另一种喊法:套接 字。它包含有IP 地址和端口号的信息,是通信的必要条件。套接字就是一个文件, 是int 型数字,它与文件描述符共用一段数值空间0-65535。应用程序中使用套接 字来调用套接口,套接字可以认为是指向套接口的指针。Socket 是网络传输层供 给应用层的编程接口,它提供了许多函数和例程,程序员可以使用它们来开发 TCP/IP 网络应用程序。套接字归根结底就是文件描述符。使用Socket 进行数据传 输的简要步骤如下:建立一个Socket,返回该套接字的描述符;按要求配置socket 的端口和ip 地址,将socket 连接到服务端和客户端;按要求通过socket 发送和 接收数据;关闭此socket。 (2)功能:在Internet 上的主机大多数情况都会有很多应用程序,每种应用程序 对应着一个服务相当与就是客户端。每种服务都打开一个 Socket,并把服务端和 客户端指定绑定到系统中的同一个端口上,而且这个端口必须相同且不能为系统 所占用的端口。进程之间的通信需要端点这样的标志,socket 就提供了这种标志。 所以不同进程之间要通过socket 提供的端点才能使进程之间相关联起来进行数据 传输。 服务端和客户端的数据通信,我们可以这样理解,就是把客户端套接字里面 的内容传输到服务端套接字里面去,两个套接字建立一种关联,该关联应该包含 多个元素用来建立多个Socket,使多个客户端与指定的ip 和端口号建立联系。 这里值得一提的是,socket 是面向客户/服务器模型而设计的面对不同客户 端和服务端程序提供不同的socket 系统调用。Socket 实际上是网络传输层和应用 层之间的桥梁。客户向内核任意请求一个socket,系统会立刻为之分配一个socket 号,服务器拥有全局公认的 socket ,所有在局域网或者在Internet 网上的客户 端可以进行连接请求。socket 利用 模式很好地解决了不同进程之间数据传输的问题,所以它可以在本地局域网上进行通信,也可以通过互联网在世界范围内 通信。 3.2 socket 类型 主要有三种类型: 流式套接字(SOCK_STREAM):流套接字用在提供面向连接、可靠的数据传输环 境中。这种套接字类型能达到数据传输的稳定可靠性。流套接字能够保证数据传 输的准确和可靠性,原因在于其使用了TCP 协议。 数据报套接字(DGRAM):该类型套接字适用于无连接的环境中。对数据是否成 功传达,不做检测,所以数据丢失风险很大,也无法保证顺序地接收到数据。这就是我们所说的udp 协议。数据报最大长度为64KB。 原始套接字(SOCK_RAW) :允许对较低层的协议,如IP,ICMP 进行直接访问。 用于检验新的协议和服务中配置的新装备。因此,如果要访问其他协议发送数据 必须使用原始套接字。 3.3 socket 函数 3.3.1 API 功能介绍 Socket()作用:向系统注册一个套接字。 格式:int socket(int add_f,int mode,int deal)。 参数说明: add_f:表示地址族,可以是AF_UNLX 和AF_INT。这里我们要使用AF_INT。 mode:网络程序所采用的通信协议,可以取 SOCK_STREAM SOCK_DGRAM。其中,SOCK_STREAM 表明使用的是TCP 协议,提供可靠连接;SOCKE_DGRAM 表明使用 的是UDP 协议,提供不可靠连接。 deal:一般默认为0。 bind()作用:用来设置名称,具体设置如下: Struct sockaddr_in server_addr; server_addr.sin_family=AF_INET;//协议类型,这里是TCP/IP 协议 server_addr.sin_port=htons(PORT);//指定端口号 server_addr.sin_addr.s_addr=htonl(INADDR_ANY);//表示任意IP 这里有个小知识需要我们关注一下,不然在运行程序时可能报错。问题就是 当申明的时候是用的 Struct sockaddr,而在使用的时候总是强制转换成 struct sockaddr_in。而对于 sin_port sin_addr.s_addr需要转化成网络字节优先顺 格式:intbind(int b_fd,struct sockaddr *server_addr,int addrlen)。 参数说明: b_fd:绑定的套接字符。 server_addr:用来存放源主机信息比如IP 地址和端口。 Addrlen:设置结构大小长度。 listen()和accept()作用:监听客户端连接请求,接收客户端请求。 格式:int listen(int intbacklog)。 格式:intaccept (int s1, void *addr, int *addrlen)。 参数说明: s:服务端监听客户端的套接字符。 Backlog:表示接入队列允许的连接数目,大多数系统允许20 参数说明:s1:服务端接收客户端的套接字符。 Addr:包含主机地址数据的结构。 Addrlen:表示地址的长度。 connet()作用:将socket 连接至serv_addr 指定的网络地址。 格式:int connect( int sockfd structsockaddr *serv_addr intaddrlen)。 参数说明: sockfd:客户端的描述符。 serv-addr:表示来访目的端口和ip 地址(套接字)的数据结构。 Addrlen:表示地址的长度。 send()和recv()作用:发送和接收信息。 格式:int send (int sockfd, const vod *msg,int len, unsigned int flags)。 int recv (int sockfd void*buf,int len1, usigned int flags)。 参数说明: Sockfd:指定写入数据的套接字描述符。 Sockfd1:指定读出数据的套接字描述符。 Msg:存入写入数据存放的缓冲区。 Len:数据长度。 Flags:一般设置为0。 Buf:读出数据存放的缓冲区。 Len1:buf 的长度。 close()作用:关闭文件描述符。 格式:Close( int sockfd)。 参数信息: Sockfd:关闭服务端或者客户端的描述符。 3.3.2套接口地址结构 Linux 中支持很多的套接口地址结构,这里只说明了IPV4 套接口地址结构。 在这些地址机构中包括了几个很重要的网络信息,它们是:本地主机端口,目的 主机端口,通信协议,本地协议地址,目的主机地址。这几个协议在网络连接中 起到重要作用。 /*用来存储套接字地址*/ struct sockaddr unsignedshort sa_family; //地址族 char sa_data[14]; sa_family