Linux 下基于 socket 多线程并发通信的实现


Linux 下基于 socket 多线程并发通信的实现 王远洋 周渊平 郭焕丽 (四川大学 电子信息学院 成都 610065) 摘要:在 Linux 下开发网络通信系统可以充分发挥 Linux 系统出色的网络性能,本文介绍了在 Linux 操作 系统下基于 TCP/IP 协议 Socket 套接口的通信机制以及多线程编程知识与技巧,并给出多线程方式实现多 用户与服务端(C/S)并发通信模型的详细算法,最后展现了用 C 编写的多用户与服务器通信的应用实例并附 有运行结果及截图。 关键词:Linux;套接字;多线程;并发服务器; 中图分类号:TP316.81 文献标识码:A The accomplishment of multi-pthread Communication Based on socket model in the Linux WANG Yuan-yang ZHOU Yuan-ping (School of Electronical Information, Sichuan University, Chengdu 610065, China) Abstract: Developing the network communication system in the OS of Linux can fully show the excellent speciality of Linux, This paper firstly introduced the socket communication mechanism and the knowledge of multi-pthread programming, and it also gives the detailed algorithm of multi-pthread way to accomplish multi-client to service model. In the end this paper exhibited a example application which written by C language with the result photos. Keywords: Linux; socket; multi-thread; concurrent server; 1 引言 Socket 是建立在传输层协议(主要是 TCP 和 UDP)上的一种套接字规范,最初由美国加 州 Berkley 大学提出,为 UNIX 系统开发的网络通信接口,它定义了两台计算机之间通信的 规范,socket 屏蔽了底层通信软件和具体操作系统的差异,使得任何两台安装了 TCP 协议 软件和实现了 Socket 规范的计算机之间的通信成为可能,Socket 接口是 TCP/IP 网络最为通 用的应用接口,也是在 Internet 上进行网络程序应用开发最通用的 API[1],本文介绍了Socket 通信的基本机制以及采用多线程技术实现并发通信的基本原理,并给出实例。 2 Socket 基本原理 2.1 套接字的基本概念 套接字是进行程序间通信(IPC)的一种方法,通信的基石是套接字,在客户机/服务 器通信模型当中,一个套接字就是通信的一段,这意味着套接字用来让一个进程和其他的进 程互通信息,套接字是网络通信的基本操作单元,它提供了不同主机间进程双向通信的端点, 这些进程在通信前各自建立一个Socket,并通过对Socket的读/写操作实现网络通信功能[2]。 2.2 套接字的分类 Linux系统支持多种套接字类型,主要有以下3种: 1) 流式套接字(SOCK_STREAM):这是最常用的套接字类型。 TCP协议使用此类接口, 它提供面向连接的、无差错的网络信息包的传输。 2) 数据报套接字(SOCK_DGRAM):UDP协议使用此类接口,它是无连接的服务,以独 立的数据报进行网络传输。数据报的最大长度为32KB,传输不保证顺序性、可靠性和无重复 性,它通常用于单个报文传输或可靠性不重要的场合。 3) 原始套接字(SOCK_RAW):提供对网络下层通信协议(如IP协议)的直接访问,它一 般不是提供给普通用户的,并主要用于开发新的协议或用于提取协议较隐蔽的功能[3]。 2.3 套接字的编程原理 本文主要讨论面向连接的流式套接字,我们已经知道,套接字编程均采用客户机/服务 http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 器(C/S)的协作模式,即由客户进程向服务器进程发出请求,服务器进程执行被请求的任 务并将响应结果返回给客户进程[4],客户端进程与服务器进程交互的过程如图1所示。 图1 socket通信示意图 服务器端程序的编写步骤:第一步:调用socket()函数创建一个用于通信的套接字。第 二步:给已经创建的套接字绑定一个端口号,这—般通过设置网络套接口地址和调用bind() 函数来实现。第三步:调用listen()函数使你的套接字成为一个监听套接字。第四步:调用 accept()函数来接受客户端的连接,这时就可以和客户端通信了。第五步:处理客户端的连 接请求。第六步:终止连接。 客户端程序的编写步骤:第一步:调用socket()函数创建一个用于通信的套接字。第二 步:通过设置套接字地址结构,说明客户端要与之通信的服务器的IP地址和端口号。第三步: 调用connect()函数来建立与服务器的连接。第四步:调用读写函数发送或者接收数据。第五 步:终止连接。 2.4 基本套接字函数 1) 创建socket函数 int socket(int domain,int type,int protocol);该调用有三个参数:domain、type、protocol。 参数domain指定协议地址簇,type为通信类型,protocol指明socket所用的协议。对于TCP而 言,取值分别为:PF_INET,SOCK_STREAM,0。 2) 绑定套接字与地址信息 int bind(int s,const struct sockaddr *name,int namelen);该函数将套接字地址(本地主机地 址和端口地址)与所创建的套接字联系起来。 3) 监听连接 int listen(int sockfd,int backlog);该函数有两个参数,sockfd是调用socket()返回的套接字 文件描述符,backlog表示队列中允许的最大连接数目。 4) 建立套接字连接 int connect(int sockfd,struct sockaddr *serv_addr,int addrlen);该函数有三个参数,sockfd 是调用socket()返回的套接字文件描述符, serv_addr是保存着目的地端口和IP地址的数据结 构struct sockaddr。addrlen为struct sockaddr的长度。 5) 接受请求 int accept(int sockfd,struct sockaddr *addr, int *addrlen);当服务器收到来自客户端的连 接请求时,调用该函数接受请求。 6) 数据传输 int send(int sockfd, const void *msg, int len, int flags); http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 int recv(int sockfd, void *buf, int len, unsigned int flags); 这两个函数用于流式套接字的通信,send()函数返回实际发送的数据长度,若小于 len, 则说明数据没有全部发送,需要进行再次发送剩余的部分。recv()函数返回实际接受的数据 长度。sockfd 是你想发送数据的套接字描述符,msg 是指向你想发送的数据的指针。len 是 数据的长度。flags 通常为 0,buf 是接受的信息缓冲区。 7) 关闭套接字 int close(int sockfd);该函数用于关闭套接字连接,sockfd 是套接字文件描述符,结束客 户进程和服务进程在 sockfd 上的通信。 3 多线程 socket 编程 3.1 多线程并发的优点 同一进程可以包括多个线程,这些线程共享相同的内存空间,而进程都有各自独立的内 存空间,进程之间通信需要专门的机制,这无疑增加了内核的开销,降低了系统性能[5]。线 程带来的开销很小,内核无需单独复制进程的内存空间或文件描述符等,这就大量地节省了 CPU时间,使得创建线程比进程的速度快数十倍。另外,多线程程序作为一种多任务、并发 的工作方式,还有以下的优点:1)提高应用程序响应时间;2)使多CPU系统更加有效;3) 改善程序结构。 3.2 多线程并发服务器算法 前面已经讲述了套接字实现的基本方法,但是,在实际应用中,该种服务器运行效率很 低,因为它属于重复性服务器,即只有处理完上一个客户请求以后,才能处理下一个客户请 求,而采用并发技术可以一次处理多个客户请求,可极大的提高服务器的工作效率,Linux 系统支持三种并发方式:多进程、多线程、以及 I/O 多路复用[6]。而多线程技术是并行技术 中开销较小,效率较高的一种方式,与其他两种方式相比,线程占用更少的系统资源,而且 效率更高,是并发技术中最常用的方式。其服务器算法如图 2 所示: 图 2 多线程并发服务器算法 3.3 主要的线程函数调用 Linux操作系统提供了LinuxThreads库,它是符合POSIX标准的内核级多线程函数库。在 库中提供了一些多线程编程的相关函数,在多线程编程时应包括pthread.h文件,链接时需要 用库libpthread。 1) 子线程的创建 int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);调用此函数可以创建一个新的线程,新线程创建后执行start_routine函数,其 中参数attr是线程属性,arg是向start_routine函数传递的参数。当成功创建一个新线程时,系 统会自动为新线程分配一个线程ID号,并通过pthread返回给调用者。 2) 等待线程结束 http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 int pthread_join(pthread_t thread, void **value_ptr);该函数挂起当前进程直到所等待的线 程结束。 3) 线程退出 void pthread_exit(void *value_ptr);该函数用于终止当前线程,并返回状态值。 4 多线程通信系统编程实例 4.1 实例功能 下面,我们通过一个具体的实例来说明多线程并发通信系统的具体实现,具体功能为: 服务器端:循环等候客户连接请求,一旦有客户连接请求,开启一个子线程接受并处理 客户请求,接受来自客户的信息。然后将客户信息反转后再返回给客户端。主线程继续等待 其他客户请求。服务器具有同时处理多个用户的能力。 客户端:首先与服务器建立连接,然后向服务器发送数据进行交互,接受服务器的反馈 信息并显示,之后继续等待用户输入直至用户输入ctrl+D结束通信。客户端接到输入ctrl+D 后,客户端关闭连接并退出。 4.2 实验结果测试 在虚拟机Linux上开三个终端,一个运行server,另外两个分别运行client1和client2,用 127.0.0.1本机地址回环进行模拟测试,具体过程如下: 1) 先编译client.c和server.c gcc client.c –o client -lpthread gcc server.c –o server –lpthread 2) 运行 server: ./server 3) 分别运行客户端 1、2,并输入相应信息 ./client 127.0.0.1 运行结果分别如图 3、图 4、图 5 所示: 图 3 服务器截图 图 4 客户 1 截图 图5 客户2截图 5 小结 由以上截图可知,服务器可以并发响应与多个客户端请求并同时与之通信,这样极大的 提高了服务器的运行效率和响应速度,尽管如此,在多线程编程当中还是有很多需要注意的 地方,比如说线程安全问题、线程同步等问题。只要正确处理好以上问题,并运用本文提出 的多线程并发服务器结构,就可以利用多线程开发出高效实用的大型网络通信应用程序,因 http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 此多线程技术具有十分宝贵的应用价值和广阔的应用前景。本文作者创新点:通过 Linux 下 socket 通信与多线程编程技巧相结合,实现了并发服务器模型,大大提高服务器工作效率。 参考文献 [1] 周炎涛,李立明. TCP/IP 协议下网络编程技术的实现[J]. 航空计算技术,2002,32-3:122-125 [2] 朱斌.Linux Socket 编程及其在无线网关中的应用[J]. 微计算机信息,2007,12-2:21-23 [3] 天夜创作室. linux 网络编程技术[M]. 北京:人民邮电出版社,2001:59-60 [4] (美)W.Richard Stevens. Unix 网络编程卷一:套接口 API 和 X/Open 传输接口 API[M],施振川等译, 北京:清华大学出版社,2001:160-163 [5] 郑燕飞,余海燕. Linux 得多线程机制探讨与实践[J]. 计算机应用,2001,21-1:81-83 [6] 宋燕红,马礼. 多线程并发服务器的实现[J]. 华北工学院学报,1998,19-2:124-126 作者简介: 王远洋(1984- ),男,重庆人(汉族),四川大学电子信息学院研究生,硕士,研究方向:信号与信息处理。 周渊平(1955- ),男,浙江杭州人(汉族),四川大学电子信息学院教授、博士生导师,博士,研究方向: 无线通信理论及系统,智能天线及 MIMO 技术。 郭焕丽(1983- ),男,重庆人(汉族),四川大学电子信息学院研究生,硕士,研究方向:智能天线,自适 应信号处理。 Biography: WANG Yuan-yang(1984- ), Male(Han Nationality), ChongQing Province, Undergraduate student of School of Electronical Information, Sichuan University,Resarch area: signal and informational processing. ZHOU Yuan-ping(1955- ), Male(Han Nationality), ZheJiang Province, Professor of School of Electronical Information,Sichuan University, Research area: wireless communication theory and system、smart antenna and MIMO technology. GUO Huan-li(1983- ), Female(Han Nationality), HuBei Province, Undergraduate student of School of Electronical Information, Sichuan University,Resarch area: smart antenna and adaptive signal processing. http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛 http://www.elecfans.com 电子发烧友 http://bbs.elecfans.com 电子技术论坛
还剩5页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

jqwns

贡献于2013-03-03

下载需要 3 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf