嵌入式课程设计_第1页
嵌入式课程设计_第2页
嵌入式课程设计_第3页
嵌入式课程设计_第4页
嵌入式课程设计_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、成都学院(成都大学)课程设计报告i linux tcp 服务器 / 客户端通信程序摘要: 随着计算机网络的不断发展,网络编程变得越来越重要,除了简单的web编程外,还包括利用套接字( socket )进行客户 /服务器应用程序的设计。本文先对与套接字相关的概念和函数作了一般性介绍,并提出多线程的编程方法和设计流程,也就具体的工程实例进行了流程分析。本文中,对计算机的网络模型进行了简要的分析,并对tcp的握手模型进行了概述;在多线程编程中,本文详细分析了多线程的互斥模型,讲解了多种线程之间的同步方法,并在程序设计中得到体现,详细讲述了 linux 中的 tcp服务器 / 客户端通信程序,并对结果

2、进行了验证。关键字: 网络编程;多线程;套接字成都学院(成都大学)课程设计报告ii 目 录绪论 . .1 1. 课程背景. 1 2. 选题的目的和意义. 1 3. 国内外研究现状. 1 4. 主要研究内容. 1 第 1 章 需求分析 .3 1.1 设计目的. 3 1.2 课题要求. 3 1.3 任务分析. 3 第 2 章 环境搭建 .4 2.1 ubuntu系统安装 . 4 2.2 开发环境搭建. 7 2.2.1 nfs环境介绍 . 7 2.2.2 nfs安装 . . 7 2.2.3 挂载 nfs文件系统. 7 2.2.4 交叉工具安装. 8 第 3 章 软件设计 .9 3.1 tcp/ip协

3、议 . . 9 3.1.1 网络模型. 9 3.1.2 tcp连接 . . 9 3.2 多线程编程. 10 3.3 socket网络编程模型. 12 3.3.1 tcp server编程模型 . 12 3.3.2 tcp client编程模型 . 13 3.4 程序设计. 13 3.4.1 主要内容. 13 成都学院(成都大学)课程设计报告iii 3.4.2 服务器端程序设计. 14 3.4.3 客户端程序设计. 16 第 4 章 综合测试. 18 4.1 功能测试. 18 第 5 章结论 .20 参考文献 . .21 附录一服务器端程序 .22 附录二客户端程序 .32 成都学院(成都大学)

4、课程设计1 绪论linux 经历了 20 多年的发展,已经成为了一个功能强大而稳定的操作系统,在嵌入式系统中也得到广泛的运用,伴随着物联网技术的普及,网络通信在嵌入式系统中扮演着举足轻重的作用。1.课程背景随着时代的发展,网络通信在我们的生活中愈来愈重要,在互联网技术基础上延伸和扩展来的物联网技术,正逐渐改变着我们的世界。互联网在现实生活中的应用很广泛,互联网给我们的现实生活带来了很大的方便;互联网是全球性的,这也就意味着我们能够打破时空的界限,通过互联网接触到世界的每一个角落;因为互联网的强大力量,这个时代的文明发展得到极大地提高。2.选题的目的和意义由于互联网超乎寻常的强大力量,改变了这个

5、时代的交流方式,改变着人们的生活,未来,我们还将在互联网领域得到更多的进步,会影响生活中的方方面面。3.国内外研究现状互联网从诞生至今,让人类文明得到巨大的推动,伴随着互联网的发展,各种依托互联网的技术得到迅速发展,linux 操作系统依据其优良的性能和网络功能,在各个领域都得到极大的普及。21 世纪,是互联网发展的有一个阶段,我们国家已经将互联网的发展提升到了战略高度,明确表示要建成互联网强国,我国到目前为止,已经诞生了一大批优秀的互联网企业,全世界都将在互联网的推动下,进入一个全新的时代。4.主要研究内容设计 tcp服务器程序,使用多线程实现”生产者- 消费者“模型,建立tcp服务器,响应

6、客户端请求,发送客户端指定的请求数据。主要包括以下内容:(1)创建线程持续产生数据,数据包含(学号,姓名(拼音),年龄,身高,体重,当前系统时间(纳秒数)使用gettimeofday(),可使用队列/ 多维数组存储数据;(2)创建 tcp服务器线程, 响应多个客户端的连接,读取队列 / 数组, 向客户端发送指定 “学号”的数据。设计tcp服务器程序;成都学院(成都大学)课程设计2 (3)创建 tcp客户端接收线程,连接服务器并请求指定“学号”的数据,接收数据并存储在文件中。要求存储有意义的数据,由于tcp是基于字节流的特征,需要做组包处理;成都学院(成都大学)课程设计3 第1章 需求分析1.1

7、 设计目的通过对专业知识的熟练运用,理解linux 网络编程的流程,了解互联网的基本架构,熟悉多线程编程的思想。同时,通过本课程设计,可以培养以下能力:(1)独立工作能力与创造力;(2)综合运用专业及基础知识的能力;(3)解决实际工程技术问题的能力;(4)查阅图书资料、产品手册和各种工具书的能力;(5)书写技术报告和编制技术资料的能力。1.2 课题要求使用多线程实现”生产者- 消费者“模型,建立tcp服务器,响应客户端请求,发送客户端指定的请求数据。1.3 任务分析创建线程持续产生数据,数据包含(学号,姓名(拼音),年龄,身高,体重,当前系统时间(纳秒数)使用gettimeofday),可使用

8、队列/ 多维数组存储数据。理解常用的数据结构,熟练掌握 c编程语言。创建 tcp服务器线程,响应多个客户端的连接,读取队列/ 数组,向客户端发送指定“学号”的数据,设计tcp服务器程序,掌握网络编程中服务器端的编程流程。创建 tcp客户端接收线程,连接服务器并请求指定“学号” 的数据, 接收数据并存储在文件中。要求存储有意义的数据,由于tcp是基于字节流的特征,需要做组包处理。掌握网络编程中客户端的编程流程。最终的目的是熟练掌握网络编程的编程方法,理解常用的数据结构的基本思想,掌握编程语言,理解多线程编程在实际工程中的应用。成都学院(成都大学)课程设计4 第2章 环境搭建2.1 ubuntu

9、系统安装考虑到windows 系统的普及程度,本课程实际将利用虚拟机来进行开发,首先我们需要搭建虚拟机开发环境。1.创建虚拟机图 2.1.1 2.选择操作系统图 2.1.2成都学院(成都大学)课程设计5 3. 配置处理器和内存图 2.1.3 图 2.1.4 成都学院(成都大学)课程设计6 4.安装系统图 2.1.55.安装成功界面图 2.1.6 成都学院(成都大学)课程设计7 2.2 开发环境搭建2.2.1 nfs环境介绍nfs (network file system)即网络文件系统,是freebsd支持的文件系统中的一种,它允许网络中的计算机之间通过tcp/ip 网络共享资源。 在 nfs

10、的应用中, 本地 nfs的客户端应用可以透明地读写位于远端nfs服务器上的文件,就像访问本地文件一样。2.2.2 nfs安装1.nfs是网络文件系统系统的缩写,可以用于 linux 和 linux 之间传递文件, 实现数据共享。安装命令如下:apt-get install nfs-kernel-server2. 修改配置文件打开 /etc/exports文件, 增加 mount -t nfs/nfs (rw,sync,no_root_squash,no_subtree_check) 开发板和其他 linux 主机可以通过网络访问/nfs 目录。3. 启动 nfs sudo service rp

11、cbind start sudo service nfs-kernel-server start 2.2.3 挂载 nfs文件系统mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 6:/opt/ /mnt 成都学院(成都大学)课程设计8 2.2.4 交叉工具安装1. 在/usr/local/下建立交叉编译器的安装目录arm:sudo mkdir /usr/local/arm 2. 将下载的交叉编译器包解压到/usr/local/arm目录下:sudo tar jxvf cross-4.2.2-eabi.tar.bz2 -c

12、 /usr/local/arm/ 3. 解压成功后,修改path环境变量:sudo vim /etc/profile 在文件为加入交叉编译器arm-linux-所在的路径:export path=$path:/usr/local/arm/4.2.2-eabi/usr/bin 4. 更新一下配置文件/etc/profile:source /etc/profile 成都学院(成都大学)课程设计9 第3章 软件设计3.1 tcp/ip 协议3.1.1 网络模型应用层物理层数据链路层网络层传输层会话层表示层osi参考模型应用层网络层传输层网络接口层tcp/ip 参考模型telnet ftp ipv4、

13、 ipv6 arp、 rarp mpls igmp icmp tcp udp 应用层传输层网络层网络接口层图 3-1-1 网络模型如图 3-1-1 所示, 在 tcp/ip 协议中, 将互联网划分成为应用层、传输层、 网络层、 网络接口层,其中网络接口层的主要功能是提供二进制传输和介质访问的功能;网络层负责ip 寻址和路由, 其中要考虑路由算法,拥塞控制等问题;传输层负责应用程序之间的连接;3.1.2 tcp连接tcp ip 一般通过internet串行线路协议slip 或点对点协议ppp在串行线上进行数据传送。tcp/ip 协议的基本传输单位是数据包 (datagram)。tcp协议负责把数

14、据分成若干个数据包/ 段,并给每个数据包加上包头,ip 协议在每个包头上再加上接收端主机地址,这样数据找到自己要去的地方。如果传输过程中出现数据丢失、数据失真等情况,tcp 协议会自动要求数据重新传输并重新组包。 tcp协议保证数据传输的质量,ip 协议保证数据的传输。数据在传输时每通过一层就要在数据上加个包头,其中数据供接收端同一层协议使用,而在接收端每经过一层要把用过的包头去掉,这样来保证传输数据的格式完全一致。tcp/ip 协议需要针对不同的网络进行不同的设置,且每个节点成都学院(成都大学)课程设计10 一般需要一个“ip 地址”、一个“子网掩码”、一个“默认网关”。不过可以通过动态主机

15、配置协议( dhcp ),给客户端自动分配一个ip 地址,这样避免了出错也简化了tcp/ip 协议的设置。如图 3-1-2 所示, tcp是通过 3 次握手建立的:1.客户端给服务器发送syn (syn = j)包,进入syn_send 状态。2.服务器接收到sync 包,确认客户的syn (ack = j+1),同时自己也发送一个syn包( syn = k ),把它俩都发送出去,服务器进入syn_send 状态。3.客户端收到服务器的syn+ack 包,向服务器发送ack (ack = k+1 ),客户端和服务器都进入 established 状态。此时,连接已经建立完毕,可以相互发送发送消

16、息。图 3-1-2 三次握手示意图3.2 多线程编程进程是系统中程序执行和资源分配的基本单位。每个进程都拥有自己的数据段、代码段和堆栈段,这就造成了进程在进行切换等操作时都需要有比较复杂的上下文切换等动作。为了进一步减少处理机的空转时间,支持多处理器以及减少上下文切换开销,进程在演化中出现了另一个概念线程。它是进程内独立的一条运行路线,处理器调度的最小单元,也可以称为轻量级进程。线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享。因此,线程的上下文切换的开销比创建进程小很多。同进程一样,线程也将相关的执行状态和存储变量放在线程控制表内。一个进程可以有多个线程,也就是有多个线程

17、控制表及堆栈寄存器,但却共享一个用户地址空间。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响。由此可知,多线程中的同步是非常重要的问题,以下是线程同步用到的一些方法:成都学院(成都大学)课程设计11 1. 互斥锁互斥锁是用一种简单的加锁方法来控制对共享资源的原子操作。这个互斥锁只有两种状态,也就是上锁和解锁,可以把互斥锁看作某种意义上的全局变量。在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。可以说,这把互斥锁保证让

18、每个线程对共享资源按顺序进行原子操作。互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁。这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待。快速锁是指调用线程会阻塞直至拥有互斥锁的线程解锁为止。递归互斥锁能够成功地返回,并且增加调用线程在互斥上加锁的次数,而检错互斥锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误信息。互斥锁机制主要包括下面的基本函数:1)互斥锁初始化:pthread_mutex_init() 2)互斥锁上锁:pthread_mutex_lock() 3)互斥锁判断上锁:pthread_mutex_trylock() 4)互斥锁解锁:pthr

19、ead_mutex_unlock() 5)消除互斥锁:pthread_mutex_destroy() 2.信号量信号量也就是操作系统中所用到的pv原子操作, 它广泛用于进程或线程间的同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。pv原子操作是对整数计数器信号量sem的操作。一次p操作使 sem减一,而一次v操作使 sem加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量sem 的值小于零时,该进程(或线程)就将阻塞直到信号量sem的值大于等于0 为止。信号量机

20、制主要包括下面的基本函数:1)创建信号量: sem_init() 2)等待信号量:sem_wait() 和 sem_trywait() 3)唤醒进程:sem_post() 4)获取信号量: sem_getvalue() 5)删除信号量: sem_destroy() 成都学院(成都大学)课程设计12 3.3 socket 网络编程模型在 linux中的网络编程是通过socket接口来进行的。socket是一种特殊的i/o 接口,它也是一种文件描述符。它是一种常用的进程之间通信机制,通过它不仅能实现本地机器上的进程之间的通信,而且通过网络能够在不同机器上的进程之间进行通信。源 ip 地址和目的ip

21、 地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务,它是网络通信过程中端点的抽象表示,包含进行网络通信必需的五种信息:连接使用的协议,本地主机的ip 地址,本地进程的协议端口,远地主机的ip 地址,远地进程的协议端口。3.3.1 tcp server 编程模型图 3-2-1 server编程模型1)进行版本协商(wsastartup)2)创建一个套接字(socket ()3)将套接字设为监听状态(listen()4)接受客户端的连接请求(accept ()5)发送或者接收数据(send() /recv ()6)关闭套接字(close ()设置为监听状态进行版本协

22、商创建套接字接受客户端的连接请求接收或者发送数据关闭套接字成都学院(成都大学)课程设计13 3.3.2 tcp client编程模型图 3-2-2 client编程模型1)进行版本协商(wsastartup)2)创建一个套接字(socket ()3)连接到服务器(connect ()4)发送或者接收函数(send() /recv ()5)关闭套接字(close ()3.4 程序设计3.4.1 主要内容设计 tcp服务器程序,使用多线程实现”生产者- 消费者“模型,建立tcp服务器,响应客户端请求,发送客户端指定的请求数据。1. 创建线程持续产生数据,数据包含(学号,姓名(拼音),年龄,身高,体

23、重,当前系统时间(纳秒数)使用gettimeofday),可使用队列/ 多维数组存储数据。2. 创建 tcp服务器线程,响应多个客户端的连接,读取队列/数组,向客户端发送指定“学号”的数据。设计tcp服务器程序。3. 创建 tcp客户端接收线程,连接服务器并请求指定“学号”的数据,接收数据并存储在文件中。要求存储有意义的数据,由于tcp是基于字节流的特征,需要做组包处理连接到服务器进行版本协商创建套接字接收或者发送数据关闭套接字成都学院(成都大学)课程设计14 3.4.2 服务器端程序设计以下是服务器端程序的主函数部分,在主函数中,首先创建了一个新的线程,然后按照网络编程模型中服务器端的编程方

24、法进行了编程,详细程序设计请参考附件1. void main(void) /*子线程相关 */ pthread_t reader = -1; /read进程的进程号pthread_mutex_init(&mutex,null); /初始化 互斥锁/*初始化数据 */ int i = 0; for(i=0; i5; i+) = namei; informationi.age = agei; informationi.number = numi; informationi.high = highi; informationi.weigh = wighti

25、; /* 创建线程 ,产生数据 */ pthread_create(&reader,null,(void*)&writer_function,null); /*主线程相关 */ /创建 socket nlistensock =socket(af_inet,sock_stream,ipproto_tcp); if(nlistensock0) printf(create listen socket errorn); return; /设置 socket选项成都学院(成都大学)课程设计15 int nvalue=1; if(setsockopt(nlistensock,sol_soc

26、ket,so_reuseaddr,(char*)&nvalue,sizeof(int)0) printf(set option so_reuseaddr fail!n); close(nlistensock); return; /绑定struct sockaddr_in localaddr; memset(&localaddr,0 x0,sizeof(localaddr); localaddr.sin_family =af_inet; localaddr.sin_addr.s_addr =htonl(inaddr_any); localaddr.sin_port =htons(

27、10000); if(bind(nlistensock,(struct sockaddr*)&localaddr,sizeof(struct sockaddr)0) printf(bind liste sock fail!n); close(nlistensock); return; /监听if(listen(nlistensock,5)0) printf(listen error!n); close(nlistensock); return; /创建客户端的线程int nsrvthreadid =1; nthreadflag =1; 成都学院(成都大学)课程设计16 if(pthre

28、ad_create(pthread_t*)&nsrvthreadid,null,(void*)&serverthreadproc,null)0) printf(create server thread fail!n); close(nlistensock); return; /等待退出while(1) if(pthread_join(nsrvthreadid,null)!=0) return; 3.4.3 客户端程序设计以下是客户端的程序设计,代码片段太过冗长,详细的程序设计请参考附件2。void main(int argc, char* argv) /创建套接字int soc

29、kfd=-1; sockfd =socket(af_inet,sock_stream,ipproto_tcp); if(sockfd0) printf(socket create errorn); return; . 成都学院(成都大学)课程设计17 /建立连接while(1) /建立链接 if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)=0) printf(connectedn); break; sleep(1); . /创建交互进程pthread_t ipt_id; if(pthread_cre

30、ate(pthread_t *)&ipt_id,null,(void*)&input,null)0) printf(create input thread fail!n); close(ipt_id); return; . 成都学院(成都大学)课程设计18 第4章 综合测试4.1 功能测试1. 运行服务器端程序,处于监听状态,等待客户端来连接,当有客户端连接上,输出连接的客户端的信息。图 4-1-1 服务器运行2. 运行客户端程序,等待用户输入要从数据库中读取的信息编号,当用户输入要读取的信息标号的时候,服务器响应客户端的请求,回复信息。图 4-1-2 客户端运行成都学院(成都

31、大学)课程设计19 3. 在当前目录下生成一个.txt文件,内部包含客户端请求的信息。图 4-1-3 生成文件4. 打开文件,内部为请求的信息。图 4-1-4 文件内容成都学院(成都大学)课程设计20 第5章 结论本次课程设计的内容是基于linux操作系统的多线程网络编程,实现的功能是 “生产者” , “消费者”模型,建立tcp服务器,响应客户端请求,并发送客户端请求的数据。在程序的设计过程中采用了多线程的编程方式,显著提高了程序运行的效率。客户端与服务器通过tcp方式建立连接,使用的通讯函数接口为套接字,套接字在网络编程中有着举足轻重的地位。通过本次课程设计,我们创建tcp服务器线程,响应多

32、个客户端的连接,读取队列 / 数组,向客户端发送指定“学号”的数据;创建tcp客户端接收线程,连接服务器并请求指定“学号”的数据,接收数据并存储在文件中;在实现的这个过程中,利用数据结构中的队列构造了数据表,方便程序访问,同时,也方便服务器端对数据的管理。通过本次课程设计,掌握了linux 下的编程模式和编程方法,熟悉了linux 的基本操作;同时,掌握了开发环境的搭建,常用的软件服务的安装,锻炼了实际的工程能力;通过多线程编程方法,理解了线程和进程的区别和联系,掌握了创建线程和注销线程的方法;通过对套接字的使用,掌握了在 linux 下基于套接字的网络编程,理解了 linux 下套接字编程在

33、服务器端和客户端的编程流程,了解了网络模型,提高了解决问题的能力。成都学院(成都大学)课程设计21 参考文献1范展源 . 深度实践嵌入式linux 系统移植 . 北京:机械工业出版社,2015.5 2宋宝华 .linux设备驱动开发详解. 北京:机械工业出版社,2015.7 3谭浩强 .c 程序设计 . 北京:清华大学出版社,2010.6 4陈文智 . 嵌入式系统设计与原理. 北京:清华大学出版社,2011.5 5宋敬彬 .liunx网络编程 . 北京:清华大学出版社,2010.6 成都学院(成都大学)课程设计22 附录一 服务器端程序/* 文件名 : server.c 文件描述 : 嵌入式课

34、程设计程序完成日期 :2017 年 9 月 8 日作者:陈凯联系方式: */ #include #include #include #include #include #include #include #include /*函数申明 */ void writer_function(void); void serverthreadproc(void *); /链表结点结构体typedef struct _client_info_ char szclientip16; int nclientport; int nclientsock; struct _client_info_ *pnext; s

35、truct _client_info_ *ppre; client_info; /*数据类型 */ typedef struct datatype unsigned char number; unsigned char age; unsigned char high; unsigned char weigh; 成都学院(成都大学)课程设计23 long time; char *name; datatype; /* 协议包结构 */ typedef struct pro_package char head; /开始标志为设定为 0 x7e 1 int lenth; /包的数据部分长度4 unsi

36、gned char flag; /0 : cmd 1:data 1 unsigned char stop; /0 stop 1:send 1 unsigned char num; /标明发送信息1 unsigned char data200; /数据部分pro_package; /*创建缓存区 */ typedef struct queue datatype buffer5; int b_tail; int b_head; queue; /*初始化队列 */ queue queue = .b_tail = 0, .b_head = 0, ; /*数据初始化 */ char *name5 = w

37、uhao, chenkai,liumenglin,liujin,liufeng; unsigned char age5 = 20,21,22,23,24; unsigned char num5 = 1,2,3,4,5; unsigned char high5 = 175,174,173,175,165; unsigned char wight5 = 58, 55, 62, 63, 50; datatype information5; /* 全局变量 */ int nlistensock =-1; /server lisen socket int nthreadflag =0; / thread

38、 start/stop flag client_info *pclienthead=null; /client list header 成都学院(成都大学)课程设计24 struct timeval sys_time; pthread_mutex_t mutex; int buffer_has_item=0; /主函数void main(void) /*子线程相关 */ pthread_t reader = -1; /read进程的进程号pthread_mutex_init(&mutex,null); /初始化 互斥锁/*初始化数据 */ int i = 0; for(i=0; i5;

39、 i+) = namei; informationi.age = agei; informationi.number = numi; informationi.high = highi; informationi.weigh = wighti; /* 创建线程 ,产生数据 */ pthread_create(&reader,null,(void*)&writer_function,null); /*主线程相关 */ /创建 socket nlistensock =socket(af_inet,sock_stream,ipproto_tcp);

40、 if(nlistensock0) printf(create listen socket errorn); return; /设置 socket选项int nvalue=1; if(setsockopt(nlistensock,sol_socket, so_reuseaddr,(char*)&nvalue,sizeof(int)0) printf(set option so_reuseaddr fail!n); close(nlistensock); return; /绑定struct sockaddr_in localaddr; memset(&localaddr,0 x0

41、,sizeof(localaddr); localaddr.sin_family =af_inet; localaddr.sin_addr.s_addr =htonl(inaddr_any); localaddr.sin_port =htons(10000); 成都学院(成都大学)课程设计25 if(bind(nlistensock,(struct sockaddr*)&localaddr,sizeof(struct sockaddr)0) printf(bind liste sock fail!n); close(nlistensock); return; /监听if(listen(

42、nlistensock,5)0) printf(listen error!n); close(nlistensock); return; /创建客户端的线程int nsrvthreadid =1; nthreadflag =1; if(pthread_create(pthread_t*)&nsrvthreadid,null,(void*)&serverthreadproc,null)nclientsock =nconnectsock; ptcpclient-nclientport =ntohs(clientaddr.sin_port); strcpy(ptcpclient-sz

43、clientip,inet_ntoa(clientaddr.sin_addr); 成都学院(成都大学)课程设计27 ptcpclient-pnext =null; ptcpclient-ppre =null; printf(client connected,ip:%s,port:%dn, ptcpclient-szclientip, ptcpclient-nclientport); if(pclienthead=null) pclienthead= ptcpclient; else ptempclient =pclienthead; while(ptempclient-pnext!=null)

44、 ptempclient =ptempclient-pnext; ptempclient-pnext =ptcpclient; ptcpclient-ppre =ptempclient; /update fd set fd_set(nconnectsock,&allset); if(nconnectsocknmaxfd) nmaxfd =nconnectsock; else /对客户端的服务 /find the client ptcpclient =pclienthead; while(ptcpclient!=null) int nrcvsock =ptcpclient-nclient

45、sock; if(fd_isset(nrcvsock,&rset)=0) ptcpclient =ptcpclient-pnext; continue; /从客户端接收数据 ,需要修改int nlen =recv(nrcvsock,ucrcvbuf,sizeof(ucrcvbuf),msg_nosignal); if(nlennclientsock =-1; /del this client info fd_clr(nrcvsock,&allset); printf(client disconnected,ip:%s,port:%dn, ptcpclient-szclienti

46、p, ptcpclient-nclientport); /del the client from list if(ptcpclient-ppre!=null) ptcpclient-ppre-pnext =ptcpclient-pnext; else pclienthead =ptcpclient-pnext; if(ptcpclient-pnext!=null) ptcpclient-pnext-ppre =ptcpclient-ppre; /free free(ptcpclient); else /对客户端请求进行组包 int i; for(i=0; inlen; i+) /寻找包头 if

47、(ucrcvbufi = 0 x7e) verify_flag = 1; break; if(verify_flag = 1) 成都学院(成都大学)课程设计29 /* 组包*/ package.head = ucrcvbufi; memcpy(&package.lenth, &ucrcvbufi+1, 4); package.flag = ucrcvbufi+5; package.stop = ucrcvbufi+6; package.num = ucrcvbufi+7; /不需要数据i = 0; /i 清 0 int g; if(package.flag = 0) int k

48、=0; /查找数据 ,组包for(k=0;kpnext; int nretval=1; pthread_exit(void*)&nretval); return; /*生产函数 */ void writer_function(void) int j=0; int ret; while(1) ret = gettimeofday(&sys_time,null);/ 获取系统时间if(ret 0) printf(get sys time fail!n); continue; pthread_mutex_lock(&mutex); /获取互斥锁0 queue.b_tail =

49、 (queue.b_tail + 1)%5; / 入队列j = queue.b_tail-1; if(j = -1) j = 4; /printf( 生产者:生产一件产品! n); queue.bufferj.age= informationj.age; /往 buffuer 里面放入数据queue.bufferj.number = informationj.number; queue.bufferj.high = informationj.high; queue.bufferj.weigh = informationj.weigh; queue.bufferj.time = sys_time

50、.tv_sec; /printf(%xn, queue.bufferj.time); 成都学院(成都大学)课程设计31 q= ; pthread_mutex_unlock(&mutex); /释放互斥锁usleep(1000); 成都学院(成都大学)课程设计32 附录二 客户端程序/* 文件名 : client.c 文件描述 : 嵌入式课程设计程序完成日期 :2017 年 9 月 8 日作者:陈凯联系方式: */ #include #include #include #include #include #include

51、 #include /* 协议包结构 */ typedef struct pro_package char head; /开始标志为设定为 0 x7e 1 int lenth; /包的数据部分长度4 unsigned char flag; /0 : cmd 1:data 1 unsigned char stop; /0 stop 1:send 1 unsigned char num; /标明发送信息1 unsigned char data40; /数据部分pro_package; /*接收数据结构体 */ typedef struct datatype unsigned char number

52、; unsigned char age; unsigned char high; unsigned char weigh; long time; char *name; datatype; /*标准包 */ pro_package test_package= .head = 0 x7e, 成都学院(成都大学)课程设计33 .lenth = 8, .flag = 0, .stop = 1, ; /global int input_flag = 6; void input(); char printf_buffer300; void main(int argc, char* argv) if(ar

53、gc!=3) printf(%s: n, argv0); return; /create socket int sockfd=-1; sockfd =socket(af_inet,sock_stream,ipproto_tcp); if(sockfd0) printf(socket create errorn); return; /connect struct sockaddr_in serveraddr; memset(&serveraddr,0 x0,sizeof(struct sockaddr_in); serveraddr.sin_family =af_inet; server

54、addr.sin_port =htons(atoi(argv2); if(inet_pton(af_inet,argv1, &serveraddr.sin_addr)=0) printf(input wrong server addrn); close(sockfd); return; while(1) /建立链接 if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)=0) printf(connectedn); 成都学院(成都大学)课程设计34 break; sleep(1); /创建交互线程

55、pthread_t ipt_id; if(pthread_create(pthread_t *)&ipt_id,null,(void*)&input,null) 5) /非法输入成都学院(成都大学)课程设计35 printf(input number false, please reinput!n); sleep(2); continue; int package_lenth = 8; send_buffer0 = test_package.head; memcpy(&send_buffer1, &package_lenth, 4); /头部为 8 个字节sen

56、d_buffer5 = test_package.flag; / 控制信息send_buffer6 = test_package.stop; send_buffer7 = (char)input_flag; send(sockfd, send_buffer, 8, msg_nosignal); /*打印发送的数据 */ /*int g; printf(send data:n); for(g=0; g8; g+) printf(%x , send_bufferg); */ int nlen =recv(sockfd,ucrcvbuf,sizeof(ucrcvbuf),msg_nosignal); /printf(len :%dn,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论