版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
xxx师范学院2015届本科毕业论文(设计)引言1.1背景在这个人才如潮涌般的世界,系统界的先驱Windows系统已经不能满足越来越多的开发人员的需求。Linux系统由于其优越的自身条件,能运行于多种平台、源代码公开、免费、功能强大、遵循POSIX标准、与UNIX兼容的操作系统等诸多优势,越来越受到开发人员的青睐。本次选课的内容选择这个系统开开发聊天工具也是因为这个原因。1.2选课意义Linux是一种能运行于多种平台、源代码公开、免费、功能强大、遵循POSIX标准、与UNIX兼容的操作系统。Linux自20世纪中期以来一直在突飞猛进地发展,人们在计算机软件开发和应用中越来越离不开它。Linux的诞生和发展给全球的软件业带来了新的机遇,也使微软的Windows操作系统面临有史以来最大的挑战。由于Linux属于自由软件,它的源代码是公开的,并遵循通用公共许可证(GeneralPublicLicence,GPL),所以用户可以免费使用,从而使Linux在极短的时间内就成了一套成熟而稳定的操作系统。全世界成千上万的程序专家和Linux爱好者正在通过Internet不断地对Linux进行开发、完善和维护【1】。1.3Linux与Windows操作系统和Linux一样,Windows是完全的多任务操作系统。它们支持同样的用户接口、网络和安全性。但Windows操作系统是商用的操作系统,由微软公司控制接口和设计。因此,用户无法对Windows做任何改动。在稳定性方面,Linux和Windows运行的稳定性各有优劣。但Linux的任何程序都是相对独立的,哪怕GNOME和KDE(窗口管理程序)也是独立的。因此软件的崩溃难以造成系统的瘫痪(死机)。此时,只要重新运行程序就可以恢复。Windows的死机频率远远高于Linux。在多用户方面,Linux是真正的多用户系统,可以有多个用户真正登录。而相对来说,Windows就很勉强;在对中文的支持方面,Windows的多个版本对于中文的支持是很强的,字体也很漂亮。而Linux虽然也支持中文,但要完全支持中文需要手动做很多设置。不过由于几乎每个软件都要设置字体和字符编码,即使做的再好,任然可能看到中文乱码,而且开源的中文字体基本都不好看。因此,Linux在中文显示上其效果不如Windows;在安全性方面,Windows的安全性是很有问题的,为此,必须安装各种杀毒软件、防火墙、防垃圾软件、防间谍软件等保证安全的软件,而这些软件的安装占去了很多的系统资源。即使这样,还是防不胜防。相对而言,Linux的安全性好很多;在应用软件方面,虽然Linux下的软件有很多,但相比Windows,还是少很多。Linux没有特定的支持厂商,而微软的商业运作很成功;在易用性方面,Windows相当容易上手,而Linux的学习成本则很高,特别是做系统配置时,Linux的复杂性就充分体现出来了。加上Linux的文档材料远不如Windows,这使得Linux的学习应用和使用成本都增加了。由于受知识产权的限制,所以无论是使用PC平台上的Windows,还是使用应用于大中型机的UNIX,都无法窥视到其内部结构。这些系统很可能存在不为我们所知的漏洞,如果这些漏洞为别有用心者所用,将会产生各种安全问题。操作系统不同于其他软件产品,它是其他应用程序得以运行的平台。由于我们无法获知这些系统的细节,所以我们无法确保计算机应用的安全,长此以往,将会对软件产业发展产生深远的负面影响。Linux的出现,一方面促进了许多国家软件产业的发展,另一方面,它也为广大的学生提供了一份宝贵的学习资料。目前UNIX、Linux、Windows三种系统三分天下,最终谁能占领市场的主流而成为市场霸主,目前还没有定论。但总的来说,Linux的发展前景是很广阔的【1】。(1)Linux的起源于发展Linux的发言为“Lin-noks”,中文发音为“利尼克斯”。它的标志是可爱的企鹅,取自芬兰的吉祥物。Linux起源于1991年,LinusTorvalds为了编写一个比Minix(由谭邦宁教授开发的一个用于操作系统教学、很小的UNIX操作系统)更好的操作系统,首次在Internet上发布了基于Intel386体系结构、类似于UNIX的Linux源代码,这就是最早的Linux版本。由于Linux具有结构清晰、功能简捷等特点,许多高等院校的学生和科研机构的研究人员纷纷把它作为学习和研究的对象。Linux的历史是和GNU紧密联系在一起的。从1983年开始的GNU计划(该计划致力于开发一个自由并且完整的类UNIX操作系统,包括软件开发工具和各种应用程序)到1991年Linux内核发布,GNU已经几乎完成了除了系统内核之外的各种必备软件的开发。在LinusTorvalds和其他开发人员的努力下,GNU组件可以运行于Linux内核之上。整个内核是基于GNU通用公共许可,也就是GPL,但是Linux内核并不是GNU计划的一部分。1994年3月,Linux1.0版正式发布,MarcEwing成立了RedHat软件公司,成为最著名的Linux分销商之一。现在,Linux的用户群一般都是专业人士。他们愿意安装并设置自己的操作系统,因而往往比其他操作系统的用户要花更多的时间。这些用户有时被称作“黑客”或“极客”(geek)。使用Linux的主要成本为移植、培训和学习的费用,早期由于会使用Linux的人较少,并且在软件设计时并未考虑到非专业者的使用,导致这方面的费用极高。这方面的费用已经随着Linux的日益普及和Linux上的软件越来越多、越来越方便而降低,但这仍是使用Linux的主要成本。然而随着Linux的慢慢开始流行,有些原始设备制造商(OEM)开始在其销售的电脑上预装上Linux,Linux的用户中也有了普通电脑用户,Linux系统也开始慢慢出现在个人电脑操作系统市场。Linux在欧洲、美国和日本的流行程度比较高,欧美地区还发行Linux平台的游戏和其他家用软件。Linux开源社区也是以欧洲、美国、日本等发达国家及地区的人士居多。每个孩子拥有一台笔记本电脑这一项目正在催生新的、更为庞大的Linux用户群,计划将包括发展中国家的几亿学童、他们的家庭和社区。在2007年,已经有6个国家分别订购了至少一百万台的笔记本电脑免费发放给学生。谷歌、RedHat和eBay是该项目的主要支持者【2】。下面简单地回顾一下Linux版本的变化过程:1991年10月,Linux第一个公开版0.02版发布。1994年3月,Linux1.0版发布。1999年,Linux2.2发布:GNOME1.0发布;支持Linux2.2的RedHat6.0发布;IBM推出全面支持Linux的计划;HP宣布支持Linux。1999年至2003年,各种Linux版本不断发布,在市场上的影响巨大。Linux内核最初是为Intel386微处理器设计的;现在,Linux内核支持从个人电脑到大型主机,甚至包括嵌入式系统在内的各种硬件设备。(2)Linux的内核Linux内核的最初版本是由LinusTorvalds编写的,为了能够使Linux更加完善,LinusTorvalds在网络锁公开了Linux的源码,邀请全世界的志愿者参与Linux的开发。由于许多专业用户自愿地开发它的应用程序,并借助Internet拿出来让大家一起修改,所以它周边的程序越来越多,Linux得到了不断的完善,并在短时期内迅速崛起,如今仍以相当快的速度在不断地发展着。Linux是一个很有发展前途的操作系统,也是为数不多可以与Microsoft旗下操作系统相竞争的操作系统。Linux内核由5个主要的子系统组成。这5个子系统分别是进程调度(SCHEN)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)【3】。各个子系统之间的依赖关系如下:进程调度与内存管理之间的关系:这两个子系统互相依赖。程序要在多道程序环境下运行,必须为之创建进程,而创建进程的第一件事,就是要将程序和数据装入内存。进程间通信与内存管理之间的关系:进程间通信子系统要依赖内存管理来支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有内存外,还可存取共同的内存区域。虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口来支持网络文件系统(NFS),利用内存管理来支持RAMDISK设备。内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统来支持交换,交换进程定期地由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。在这些子系统中,进程调度子系统是其他子系统得以顺利工作的关键。无论是文件系统的系统进程还是网络子系统的服务进程,都需要通过进程调度来获得相应的CPU时间以正常运行【4】。2需求分析2.1需求性分析2.1.1编写目的随着Linux操作系统的慢慢开始流行,将来会有越来越多的软件运行于Linux操作系统上。本次课题就是以Linux操作系统为基础设计的类似于Windows操作系统的聊天程序,使得很多安装的是Linux操作系统的人士能够像在Windows操作系统上聊天程序一样,方便的进行沟通。使用已学完的Linux系统、Gtk+界面设计、连接数据库和socket通信等功能来实现聊天系统。2.2对界面的需求1)一个显示框:用来显示发送和接受的聊天信息。2)两个复选框:(1)编辑:用来控制信息显示框来输入信息是否可编辑。(2)换行:用来控制显示框里面的文本是否可以换行。3)三个按钮:(1)历史记录按钮:查看历史记录的信息。(2)发送按钮:发送需要发出的信息。(3)关闭按钮:关闭窗口。4)一个录入框:功能是让用户可以输入需要发送的信息。5)对通信的需求:(1)绑定服务器的IP地址。(2)客户机可以实现发送接收信息。(3)服务器可以实现发送接收信息。6)对数据库的需求:聊天信息插入数据库,也可以从数据库里面取出信息。7)运行环境:Windows7系统、虚拟机、linux系统、MySql数据库。3系统应用技术3.1Gtk+界面设计Gtk+是Linux环境下用于图形用户界面开发的一个库,现在已成为类UNIX系统下开发图形界面应用程序的主流开发工具之一,并已移植到Windows上了。通过这个库,可以很方便地实现在Linux操作系统中开发图形用户界面【5】。3.1.1Gtk+基础最初Gtk+是作为另一个著名的源码项目GIMP(GNUImageManipulationProgram,)的副产品而创建的。GIMP最初是类UNIX操作系统的图像处理程序,现在也被移植到了Windows平台。为了简化GIMP的开发,专门开发了GIMPToolKit——一个生成GUI的工具库(或者,实际上是若干个密切相关的库的集合),这就是Gtk。它是一套跨多种平台的图像工具包,支持创建于GUI的应用程序(可以把Gtk+想象成一个工具包,从这个工具包中可以找到用来创建GUI的许多已经准备好的构造块)。在增加了面向对象的特性之后,它的名称后面添加了一个加号,于是就成为Gtk+。Gtk+是自由软件,并且是GNU计划的一部分,是按LGPL发布的。3.1.2Gtk+的主要特点(1)Gtk+是一个小型而高效的控件库;(2)Gtk+应用程序的国际化(i18n)、本地化(110n)提供了很好的处理工具;(3)Gtk+是可移植的,而且具有多种语言前端;(4)Gtk+为界面设计提供了配套的工具Glade;(5)提供不同的显示引擎,使得最终用户可以制定外观和质感;(6)Gtk+的应用广泛;(7)Gtk+对Windows的支持;(8)Gtk+自身特性。3.1.3Gtk+的组成(1)Gtk+工具的应用层次:GTK、GDK、GLIB;(2)Gtk+对象的层次结构:Gtk+中所有的窗口部件(Widgets)有共同的祖先——Gtk_Object,所有的可视对象有一个共同的祖先Gtk_Widget;(3)Gtk+图形库构件:提供了窗口、标签、命令按钮、开发按钮等【6】。3.2socket通信3.2.1Socket简述应用层通过传输层进行数据通信时,TCP和UDP会遇到同事为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为Socket的接口【1】。3.2.2Socket的主要类型(1)流式套接字提供一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收。(2)数据报套接字提供一个无连接服务。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。(3)原始式套接字该接口允许对较低层协议直接访问,常用于检验新的协议实现或访问现有服务中配置的新设备。Socket()函数原型:intsocket(intdon=main,inttype,intprotocol);3.2.3Socket组要在如下两类系统中使用(1)WindowsSocket.(2)LinuxSocket.3.3MySql数据库3.3.1MySql发展历史MySql的历史最早可以追溯到1979年,有一个人叫MontyWidenius,为一个叫TcX的小公司打工,并用BASIC设计了一个报表工具,可以在4M主频和16KB内存的计算机上运行。过了不久,又将此工具,使用C语言重写,移植到Unix平台,当时,它只是一个很底层的面向报表的存储引擎。这个工具叫做Unireg。1990年,TcX的customer中开始有人要求要为它的API提供SQL支持,Monty决心自己重写一个SQL支持。1996年,MySQL1.0发布,相当于内部发布。1996年10月,MySQL3.11.1发布了,没有2.x版本。最开始,只提供了Solaris下的二进制版本。一个月后,Linux版本出现了。MySql3.22应该是一个标志性的版本,提供了基本的SQL支持。MySql关系型数据库于1998年1月发行第一个版本。它使用系统核心提供的多线程机制提供完全的多线程运行模式,提供了面向C、C++、Eiffel、Java、Perl、PHP、Python以及Tcl等编程语言的编程接口(APIs),支持多种字段类型并且提供了完整的操作符支持查询中的SELECT和WHERE操作。MySql是开放源代码的,因此任何人都可以在GeneralPublicLicense的许可下下载并根据个性化的需要对其进行修改。MySQL因为其速度、可靠性和适应性而备受关注。1999-2000年,有一家公司在瑞典成立了,叫MySQLAB,雇了几个人,与Sleepycat合作,开发出了BerkeleyDB引擎,因为BDB支持事务处理,所以,MySQL从此开始支持事务处理了。2000年4月,MySQL对旧的存储引擎进行了整理,命名为MyISAM。同时,2001年,HeikikiTuuri向MySQL提出建议,希望能集成他们的存储引擎InnoDB,这个引擎同样支持事务处理,还支持行级锁。MySql与InnoDB的正式结合版本是4.0。到了MySQL5.0,2003年12月,开始有View,存储过程之类。在2008年1月16号MySQL被Sun公司收购。3.3.2MySql的常用命令(1)使用SHOW语句找出在服务器上当前存在什么数据库mysql>SHOWDATABASES;(2)创建一个数据库MYSQLDATAmysql>CREATEDATABASEMYSQLDATA;(3)选择你所创建的数据库mysql>USEMYSQLDATA;(按回车键出现Databasechanged时说明操作成功!)(4)查看现在的数据库中存在什么表mysql>SHOWTABLES;(5)创建一个数据库表mysql>CREATETABLEMYTABLE(nameVARCHAR(20),sexCHAR(1));(6)显示表的结构mysql>DESCRIBEMYTABLE;(7)往表中加入记录mysql>insertintoMYTABLEvalues(”hyq”,”M”);(8)删除表mysql>dropTABLEMYTABLE;(9)清空表mysql>deletefromMYTABLE;(10)更新表中数据mysql>updateMYTABLEsetsex=”f”wherename=’hyq’;(11)数据库/数据表/数据列权限①ALTER:修改已存在的数据表(例如增加/删除列)和索引。②CREATE:建立新的数据库或数据表。③DELETE:删除表的记录。④DROP:删除数据表或数据库。⑤INDEX:建立或删除索引。⑥INSERT:增加表的记录。⑦SELECT:显示/搜索表的记录。⑧UPDATE:修改表中已存在的记录。3.3.3MySql的重要特性(1)内部结构和可移植性;(2)极快的基于线程的内存分配系统;(3)列类型;(4)语句和函数;(5)安全;(6)连接性;(7)本地化;(8)客户端和工具。4设计和实现4.1Gtk+界面设计(1)服务器端运行结果如图所示:图4-1服务器端(2)客户端运行结果如图所示:图4-2客户端(3)控制摆放流程图本次实验设计到了hbox、vbox、text、entry以及button等控件的摆放及使用。首先在window窗口中放置一个hbox来方便后来其他控件的摆放。控件摆放如下所示:图4-3控制摆放流程图4.2连接数据库(1)连接成功截图图4-4连接成功截图(2)流程图图4-5流程图4.3网络通信socket编程4.3.1socket编程方法(1)网络连接函数Socket创建套接字Bind绑定本机端口Connect建立连接Listen监听端口Accept接受连接Recv,recvfrom数据接收Send,sendto数据发送Close,shutdown关闭套接字(2)连接流程图图4-6连接流程图4.3.2客户端/服务器工作流程1)服务器首先,应该在服务器端使用Socket()建立一个通信端口,再用bind()命令把一个地址绑定到这个端口上。然后,服务器端使用listen()监听连接请求,当远程的客户机试图使用connect()连接listen()正在监听的端口时,连接将会在队列中等待,直到使用accept()处理它。在accept()处理了连接请求之后,将会生成一个新的描述这个连接端口的套接字,利用这个套接字就可以发送和接收数据。如果listen()一直没有监听到连接请求,那么服务器任务就会在accept()处阻塞,直到有连接请求到来为止。2)客户端客户端处首先用Socket()建立一个通信端口,然后直接用connect()向指定的服务器发送连接请求,如果请求被接收,下一步就可以进行数据通信了。3)函数格式(1)Socket()作用:socket函数为客户机或服务器创建一个sokcet格式:intsocket(intfamily)Family表示地址族(2)bind()作用:bind函数是将套接字绑定到IP地址格式:intbind(intsockfd,structsockaddr*addr,intaddrlen)参数说明:Sockfd:socket的文件描述符号;Sockaddr:表示名字所用的一个数据结构,用来保存地址(包括IP地址和端口);Addrlen:设置结构大小长度。(3)listen()作用:监听连接信号,和accepted函数合同。格式:intlisten(intsockfd)参数说明:Sockfd:表示socket调用返回的文件描述符。(4)accept()作用:与listen函数合用,监听信息、接收客户端请求。格式:Intaccept(intsockfd,void*addr,int*addrlen)参数说明:Sockfd:表示socket的文件描述符;Addr:表示指向局部的数据结构structsockaddr-in的指针;Addrlen:表示地址的长度。(5)connect()作用:在面向连接的系统中客户及连接服务器时使用,connect必须在bind后使用。格式:intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen)参数作用:Sockfd:表示socket的文件描述符;Serv-addr:表示村访目的端口和ip地址(套接字)的数据结构。(6)send()和recv()Send作用:发送信息。格式1:Intsend(intsockfd)Recv作用:用于流式socket、数据报socket内部之间的通信。格式2:Intrecv(intsockfd)(7)close()格式:Close(intsockfd)4.3.3结果截图图4-6结果截图5系统测试5.1实现Gtk+界面设计(1)测试时出现的错误在用Gtk+进行界面设计时,出现了很多意想不到的错误,比如,刚开始摆放控件时竟然把Vbox和Hbox弄反了,结果出现的图形从竖着变成了横着。在放完基本的按钮时发现控件全部聚集在了一起,后来把所有的控件都放进去才出现了正常的界面。界面刚出来时,按钮那一块显得特别挤,后来在同学的帮助下,知道了需要改正一下后面的参数,比如把0改为10,可以调节按钮的外观,使按钮看上去显得不那么小气。在刚开始加图片时,每次都是出来一个红色的小叉叉,后来网上查了一下,原来是图片放错了位置,图片可以直接放进程序的那个文件夹里。(2)修改后截图图5-1正确的服务器图5-2正确的客户端5.2实现连接数据库(1)调试时出现的错误在完成程序进行测试时,因为数据库连接出现问题发送信息无法插入数据库,经过更改后进行了解决。查询聊天记录时,显示的聊天记录一直向后排列,没有换行显示效果不好,解决方法:在每条数据显示后插入换行,使其按发送条数排列整齐。(2)修改后截图图5-3修改后截图5.3实现socket通信(1)测试时出现的错误:运行后出现界面,但输入信息发送信息时界面消失。(2)修改后截图图5-4修改后截图(服务器)图5-4修改后截图(客户端)参考文献[1]蔡建平.《软件综合开发案例教程》--Linux、GCC、MySQL、Socket、Gtk+与开发案例,2005[2]赵敏哲.《64位Linux操作系统与应用实例》.北京机械工业出版社,2001[3]庞丽萍.《操作系统原理》(第三版).武汉华中科技大学出版社,2000[4]张饶学.《计算机下载系统教程》(第二版).习题解答与实验指导.北京清华大学出版社,2000[5]李胜利,庞丽萍.《操作系统》.武汉华中科技大学出版社,2002[6]胡明庆,高巍,钟梅.《操作系统教程与实验》.北京清华大学出版社,2007致谢通过本次课程设计对Linux网络聊天系统的设计,确实积累和总结了不少的经验,锻炼了我的独立工作和实际动手能力,加深了对计算机网络中socket工作原理及其相互联系的认识,提高了对复杂的综合性实践环节具有分析问题、解决问题、概括总结的实际工作能力,对网络编程项目的开发、设计过程有初步认识。经过近了多次的设计和开发,ZZ聊天界面的设计设计完毕。其功能基本符合规定需求,能够简单的网络聊天功能。但是由于我学艺不精,还有许多不尽如人意的地方,还有待于我进一步完善其功能。但我从中学到了不少的道理,真正的理解到,理论与实践之间还是有很大的距离,这必将有利于我以后的学习。使我明白,在以后的学习中,要不断的完善自己的知识体系结构,注意理论与实践的结合,学知识关键是要学活,而不能死记死搬书本上的知识,关键是要会灵活应用,这样所学到的东西才真正的学以致用,才达到了学习的真正目的!在本次课题程序设计中,我学到了很多东西,通过本次课题程序设计,无论在理论上还是在实践中,我的计算机应用水平得到了很大的提升,这对于今后的工作和学习都是一种巨大的财富。此次的课题设计让我学到了很多知识,跨越了传统方式下的教与学的体制束缚,在设计过程中,通过查资料和搜集有关的文献,培养了自学能力和动手能力,提升了知识利用率。附录Gtk+界面设计代码:(1)服务器端代码如下:intmain(intargc,char*argv[]){GtkWidget*window;GtkWidget*vbox1,*vbox2;GtkWidget*hbox1,*hbox2,*hbox3,*hbox4,*hbox5,*hbox6,*hbox7;GtkWidget*button1,*button2,*button3;GtkWidget*entry,*separator1,*separator2,*separator3,*view;GtkWidget*label1,*label2,*image1,*image2;GtkWidget*checkbutton1,*checkbutton2;gtk_init(&argc,&argv);window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗体gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,TRUE);//窗口可变gtk_window_set_title(GTK_WINDOW(window),"ChatWindowServer");//窗口名称gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);//窗口位置gtk_window_set_default_size(GTK_WINDOW(window),460,400);//窗口初始化gtk_container_set_border_width(GTK_CONTAINER(window),10);//边框hbox1=gtk_hbox_new(FALSE,0);gtk_container_add(GTK_CONTAINER(window),hbox1);//将hbox1加入windowvbox1=gtk_vbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(hbox1),vbox1,FALSE,FALSE,0);//将vbox1加入hbox1separator1=gtk_vseparator_new();gtk_box_pack_start(GTK_BOX(hbox1),separator1,FALSE,FALSE,0);//将竖向分隔符放入hbox1中vbox2=gtk_vbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(hbox1),vbox2,FALSE,FALSE,0);//将vbox2加入hbox1view=gtk_scrolled_window_new(NULL,NULL);gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(view),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);//设置竖向滚动条text=gtk_text_view_new();gtk_box_pack_start(GTK_BOX(vbox1),view,TRUE,TRUE,5);//将view放入vbox1中gtk_container_add(GTK_CONTAINER(view),text);//将text放入view中buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));separator2=gtk_hseparator_new();gtk_box_pack_start(GTK_BOX(vbox1),separator2,FALSE,FALSE,0);//将横向分隔符放入vbox1中hbox2=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox2,FALSE,FALSE,0);//将hbox2放入vbox1中hbox3=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox3,FALSE,FALSE,5);//将hbox3放入vbox1中hbox4=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox4,FALSE,FALSE,5);//将hbox4放入vbox1中hbox7=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox7,FALSE,FALSE,5);//将hbox7放入vbox1中hbox5=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox2),hbox5,TRUE,TRUE,0);//将hbox5放入vbox2中hbox6=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox2),hbox6,TRUE,TRUE,0);//将hbox6放入vbox2中label1=gtk_label_new("");gtk_box_pack_start(GTK_BOX(hbox5),label1,FALSE,FALSE,0);//将label放入hbox5中image1=gtk_image_new_from_file("1.jpg");gtk_box_pack_start(GTK_BOX(hbox5),image1,TRUE,TRUE,0);//将image1放入hbox5中separator3=gtk_vseparator_new();gtk_box_pack_start(GTK_BOX(vbox2),separator3,FALSE,FALSE,0);//将separator3放入vbox2中label2=gtk_label_new("");gtk_box_pack_start(GTK_BOX(hbox6),label2,FALSE,FALSE,0);//将label2放入hbox6中image2=gtk_image_new_from_file("2.jpg");gtk_box_pack_start(GTK_BOX(hbox6),image2,TRUE,TRUE,0);//将image2放入hbox6中checkbutton1=gtk_check_button_new_with_label("Editable");gtk_box_pack_start(GTK_BOX(hbox3),checkbutton1,TRUE,TRUE,5);gtk_signal_connect_object(GTK_OBJECT(checkbutton1),"checked",GTK_SIGNAL_FUNC(entry_toggle_editable),GTK_OBJECT(window));//为checkbutton1按钮增加调用事件checkbutton2=gtk_check_button_new_with_label("Wrapwords");gtk_box_pack_start(GTK_BOX(hbox3),checkbutton2,TRUE,TRUE,5);gtk_signal_connect_object(GTK_OBJECT(checkbutton2),"checked",GTK_SIGNAL_FUNC(entry_toggle_visibility),GTK_OBJECT(window));//为checkbutton2按钮增加调用事件message_entry=gtk_entry_new();gtk_entry_set_text(GTK_ENTRY(message_entry),"");gtk_box_pack_start(GTK_BOX(hbox4),message_entry,TRUE,TRUE,6);//将entry放入hbox4中button1=gtk_button_new_with_label("history");gtk_signal_connect_object(GTK_OBJECT(button1),"clicked",GTK_SIGNAL_FUNC(button_history),GTK_OBJECT(window));//为button1按钮增加调用事件gtk_box_pack_start(GTK_BOX(hbox3),button1,FALSE,FALSE,20);GTK_WIDGET_SET_FLAGS(button1,GTK_CAN_DEFAULT);button2=gtk_button_new_with_label("send");gtk_signal_connect_object(GTK_OBJECT(button2),"clicked",GTK_SIGNAL_FUNC(button_send),GTK_OBJECT(window));//为button2按钮增加调用事件gtk_box_pack_start(GTK_BOX(hbox7),button2,TRUE,TRUE,4);GTK_WIDGET_SET_FLAGS(button2,GTK_CAN_DEFAULT);button3=gtk_button_new_with_label("close");gtk_signal_connect_object(GTK_OBJECT(button3),"clicked",GTK_SIGNAL_FUNC(button_close),GTK_OBJECT(window));//为button3按钮增加调用事件gtk_box_pack_start(GTK_BOX(hbox7),button3,TRUE,TRUE,4);GTK_WIDGET_SET_FLAGS(button3,GTK_CAN_DEFAULT);do_connect();pthread_tid2;pthread_create(&id2,0,tcp_read,&connfd);g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window));//应用程序退出时响应gtk_widget_show_all(window);//显示窗口gtk_main();return(0);}(2)客户端代码如下:intmain(intargc,char*argv[]){GtkWidget*window;GtkWidget*vbox1,*vbox2;GtkWidget*hbox1,*hbox2,*hbox3,*hbox4,*hbox5,*hbox6,*hbox7;GtkWidget*button1,*button2,*button3;GtkWidget*entry,*separator1,*separator2,*separator3,*view;GtkWidget*label1,*label2,*image1,*image2;GtkWidget*checkbutton1,*checkbutton2;gtk_init(&argc,&argv);window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//创建窗口gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,TRUE);//设置可变gtk_window_set_title(GTK_WINDOW(window),"ChatWindowClient");//名称gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);//位置gtk_window_set_default_size(GTK_WINDOW(window),460,400);//大小gtk_container_set_border_width(GTK_CONTAINER(window),10);//边框hbox1=gtk_hbox_new(FALSE,0);gtk_container_add(GTK_CONTAINER(window),hbox1);//hbox1加入windowvbox1=gtk_vbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(hbox1),vbox1,FALSE,FALSE,0);//vbox1加入hboxseparator1=gtk_vseparator_new();gtk_box_pack_start(GTK_BOX(hbox1),separator1,FALSE,FALSE,0);//竖向分隔符加入hbox1vbox2=gtk_vbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(hbox1),vbox2,FALSE,FALSE,0);//vbox2加入hbox1view=gtk_scrolled_window_new(NULL,NULL);gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(view),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);//设置滚动条text=gtk_text_view_new();gtk_box_pack_start(GTK_BOX(vbox1),view,TRUE,TRUE,5);//view加入vbox1gtk_container_add(GTK_CONTAINER(view),text);buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));separator2=gtk_hseparator_new();gtk_box_pack_start(GTK_BOX(vbox1),separator2,FALSE,FALSE,0);//横向分隔符hbox2=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox2,FALSE,FALSE,0);//hbox2加入vbox1hbox3=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox3,FALSE,FALSE,5);//hbox3加入vbox1hbox4=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox4,FALSE,FALSE,5);//hbox4加入vbox1hbox7=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox1),hbox7,FALSE,FALSE,5);//hbox7加入vbox1hbox5=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox2),hbox5,TRUE,TRUE,0);//hbox5加入vbox2hbox6=gtk_hbox_new(FALSE,0);gtk_box_pack_start(GTK_BOX(vbox2),hbox6,TRUE,TRUE,0);//hbox6加入vbox2label1=gtk_label_new("");gtk_box_pack_start(GTK_BOX(hbox5),label1,FALSE,FALSE,0);//label1加入hbox5image1=gtk_image_new_from_file("2.jpg");gtk_box_pack_start(GTK_BOX(hbox5),image1,TRUE,TRUE,0);//image1加入hbox5separator3=gtk_vseparator_new();gtk_box_pack_start(GTK_BOX(vbox2),separator3,FALSE,FALSE,0);//separator3加入vbox2label2=gtk_label_new("");gtk_box_pack_start(GTK_BOX(hbox6),label2,FALSE,FALSE,0);//label2加入hbox6image2=gtk_image_new_from_file("1.jpg");gtk_box_pack_start(GTK_BOX(hbox6),image2,TRUE,TRUE,0);checkbutton1=gtk_check_button_new_with_label("Editable");gtk_box_pack_start(GTK_BOX(hbox3),checkbutton1,TRUE,TRUE,5);gtk_signal_connect_object(GTK_OBJECT(checkbutton1),"checked",GTK_SIGNAL_FUNC(entry_toggle_editable),GTK_OBJECT(window));//设置checkbutton1的事件checkbutton2=gtk_check_button_new_with_label("Wrapwords");gtk_box_pack_start(GTK_BOX(hbox3),checkbutton2,TRUE,TRUE,5);gtk_signal_connect_object(GTK_OBJECT(checkbutton2),"checked",GTK_SIGNAL_FUNC(entry_toggle_visibility),GTK_OBJECT(window));//设置checkbutton2的事件message_entry=gtk_entry_new();gtk_entry_set_text(GTK_ENTRY(message_entry),"");gtk_box_pack_start(GTK_BOX(hbox4),message_entry,TRUE,TRUE,6);//放入entrybutton1=gtk_button_new_with_label("history");gtk_signal_connect_object(GTK_OBJECT(button1),"clicked",GTK_SIGNAL_FUNC(button_history),GTK_OBJECT(window));//设置button1的事件gtk_box_pack_start(GTK_BOX(hbox3),button1,FALSE,FALSE,20);GTK_WIDGET_SET_FLAGS(button1,GTK_CAN_DEFAULT);button2=gtk_button_new_with_label("send");gtk_signal_connect_object(GTK_OBJECT(button2),"clicked",GTK_SIGNAL_FUNC(button_send),GTK_OBJECT(window));//设置button2的事件gtk_box_pack_start(GTK_BOX(hbox7),button2,TRUE,TRUE,4);GTK_WIDGET_SET_FLAGS(button2,GTK_CAN_DEFAULT);button3=gtk_button_new_with_label("close");gtk_signal_connect_object(GTK_OBJECT(button3),"clicked",GTK_SIGNAL_FUNC(button_close),GTK_OBJECT(window));//设置button3的事件gtk_box_pack_start(GTK_BOX(hbox7),button3,TRUE,TRUE,4);GTK_WIDGET_SET_FLAGS(button3,GTK_CAN_DEFAULT);do_connect();pthread_tid2;pthread_create(&id2,0,tcp_read,&sockfd);g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),G_OBJECT(window));//应用程序退出时响应gtk_widget_show_all(window);//显示窗口gtk_main();return(0);}连接数据库代码:(1)创建数据库voidCreateDatabase(){//对数据库进行初始化if(!(mysql=mysql_init(NULL))){printf("mysql_initwrong!");mysql_close(mysql);exit(0);}//判断是否连接有Chat数据库,如果没有,创建数据库Chat及表chatif(!mysql_real_connect(mysql,"localhost","root","","Chat",0,NULL,0)){if(mysql_real_connect(mysql,"localhost","root","","test",0,NULL,0)){ sprintf(buffer,"CREATEDATABASEChat"); if(mysql_query(mysql,buffer)) { printf("CreateDatabasewrong!"); mysql_close(mysql); exit(0); } g_print("CreateDatabaseSuccess!"); sprintf(buffer,"useChat"); if(mysql_query(mysql,buffer)) { printf("useChatwrong!"); mysql_close(mysql); exit(0); } strcpy(buffer,"createtablechat(xinxivarchar(100))"); if(mysql_query(mysql,buffer)) { printf("CreateTable1111wrong!"); mysql_close(mysql); exit(0);}g_print("CreateTableSuccess!");}}//如果有Chat数据库,判断是否有chat表,如果有先删除再建表chat,若果没有,直接创建表chatelse{ sprintf(buffer,"useChat"); if(mysql_query(mysql,buffer)) { printf("useChatwrong!"); mysql_close(mysql); exit(0); } strcpy(buffer,"droptableifexistschat"); if(mysql_query(mysql,buffer)) { printf("dropTablewrong!"); mysql_close(mysql); exit(0);}//创建表chat strcpy(buffer,"createtablechat(xinxivarchar(100))");if(mysql_query(mysql,buffer)) {printf("CreateTable2222wrong!");mysql_close(mysql);exit(0);}g_print("CreateTableSuccess!");}}(2)在发送信息的同时,将发送人,发送时间及发送的信息同时插入数据库中//连接数据库if(!mysql_real_connect(mysql,"localhost","root","","Chat",0,NULL,0)){ printf("connectDatabasewrong!"); mysql_close(mysql); exit(0);}g_printf("connectok\n");//将发送人,发送时间及发送的信息同时插入数据库中sprintf(buffer,"insertintochat(xinxi)values('server:%s\n %s')",asctime(timenow),message);if(mysql_query(mysql,buffer)!=0) {printf("insertwrong!");mysql_close(mysql);exit(0);}(3)在查询聊天记录时,将数据库中的聊天记录提取出来,显示在聊天记录窗口中voidbutton_history(intargc,char*argv[]){gcharbuf1[1024]; GtkTextBuffer*buffer1; charquery[256]; MYSQL*mysql; //constchar*message;GtkTextIteriter;introws; intcount; MYSQL_RES*mysql_res; MYSQL_ROWmysql_row; GtkWidget*window; GtkWidget*hbox; GtkWidget*view; GtkWidget*text; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window),"聊天记录"); gtk_window_set_default_size(GTK_WINDOW(window),200,300); g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL); hbox=gtk_hbox_new(FALSE,0); gtk_container_add(GTK_CONTAINER(window),hbox); view=gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(view),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); text=gtk_text_view_new(); gtk_box_pack_start(GTK_BOX(hbox),view,TRUE,TRUE,5); gtk_container_add(GTK_CONTAINER(view),text);buffer1=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); gtk_widget_show_all(hbox); gtk_widget_show_all(window); if(!(mysql=mysql_init(NULL))){ printf("mysql_initwrong!"); mysql_close(mysql); exit(0); } if(!mysql_real_connect(mysql,"localhost","root","","Chat",0,NULL,0)){ printf("connectwrong!"); mysql_close(mysql); exit(0); } strcpy(query,"useChat;"); if(mysql_query(mysql,query)){ printf("nodatabaseChat"); mysql_close(mysql); exit(0); } strcpy(query,"select*fromchat;"); if(mysql_query(mysql,query)){ printf("displaywrong!"); mysql_close(mysql); exit(0); } mysql_res=mysql_store_result(mysql); rows=mysql_num_rows(mysql_res); if(rows==0){ printf("returnnull"); mysql_free_result(mysql_res); mysql_close(mysql); exit(0); } for(count=0;count<rows;count++){ mysql_row=mysql_fetch_row(mysql_res); sprintf(buf1,"%s\n",mysql_row[0]);gtk_text_buffer_get_end_iter(buffer1,&iter); gtk_text_buffer_insert(buffer1,&iter,buf1,-1);} mysql_free_result(mysql_res);客户端/服务器代码:(1)服务器代码#include<stdio.h>#include<stdlib.h>#include<gtk/gtk.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<unistd.h>#include<arpa/inet.h>#include<pthread.h>gintsockfd,connfd;structsockaddr_inserver;structsockaddr_inclient;socklen_taddrlen;gcharbuf[1024];gcharget_buf[1024];gbooleanisconnected=FALSE;staticGtkWidget*text;staticGtkTextBuffer*buffer;staticGtkWidget*message_entry;gbooleando_connect(void){GtkTextIteriter;if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){printf("Createsocketfailed\n");perror("socket()");return-1;}//初始化Socket,创建socketserver.sin_family=AF_INET;//设置服务器端地址协议为ip4server.sin_port=htons(5678);//设置端口号为5678server.sin_addr.s_addr=inet_addr("");//设置ip地址为intbind_id=bind(sockfd,(structsockaddr*)&server,sizeof(server));if(bind_id==-1){printf("Bindfailed\n");perror("bind()");return-1;}//绑定端口号和IP地址intlisten_id;if((listen_id=listen(sockfd,1))==-1){printf("listenfailed\n");perror("listen()");return-1;}//监听端口号addrlen=sizeof(client);//赋值客户端结构体长度printf("beginaccept\n");connfd=accept(sockfd,(structsockaddr*)&client,&addrlen);//阻塞主进程,直到有客户端连接printf("connfd=%d\n",connfd);if(connfd==-1){printf("acceptfailed\n");perror("accept()");return-1; }else{gtk_text_buffer_get_end_iter(buffer,&iter);//获取buffer内容,并迭代gtk_text_buffer_insert(buffer,&iter,"connectsucces\n",-1);//将迭代的数据加入字符串加入buffer中isconnected=TRUE;printf("connectsuccess\n");returnTRUE;}}voidon_delete_event(GtkWidget*widget,GdkEvent*event,gpointerdata){close(sockfd);//关闭Socket连接gtk_main_quit();//退出窗口}voidon_send(GtkButton*button,gpointerdata){constchar*message;GtkTextIteriter;gintwrite_id;printf("beginserversend\n");bzero(buf,1024);//初始化bufmessage=gtk_entry_get_text(GTK_ENTRY(message_entry));//获取输入框的值赋值sprintf(buf,"client:%s\n",message);//将字符串和message值相连接赋值给bufprintf("serversend
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 北京理工大学《植物生物学》2024 - 2025 学年第一学期期末试卷
- 软件项目质量管理
- 心理咨询和辅导
- 2026年剧本杀运营公司市场费用预算管理制度
- 2025年智能垃圾桶清洁十年技术报告
- 2026年文化娱乐产业虚拟现实报告
- 2026年及未来5年中国车厢底板市场运行态势及行业发展前景预测报告
- 小学道德与法治教学中生命教育的实施路径课题报告教学研究课题报告
- 企业盘点和对账制度
- 艺术研究院试题及答案
- 基于PLC的恒压供水控制系统的设计-毕业论文
- 人教鄂教版六年级下册科学全册知识点
- 2024年湖南生物机电职业技术学院单招职业技能测试题库及答案解析
- (正式版)HGT 22820-2024 化工安全仪表系统工程设计规范
- 工程项目施工计划书
- 2023-2024学年深圳市初三中考适应性考试英语试题(含答案)
- NB-T 47013.15-2021 承压设备无损检测 第15部分:相控阵超声检测
- 人教新起点英语五上《Unit5shopping》课件-课件
- 各品牌挖掘机挖斗连接尺寸数据
- GB/T 38697-2020块菌(松露)鲜品质量等级规格
- 三菱FX3U系列PLC编程技术与应用-第二章课件
评论
0/150
提交评论