下面通过一个简单的聊天程序来说明Socket的大致工作流程。该程序实现了一个服务器同时为多个客户端提供服务的功能。程序是基于SocketC/S模式开发的,它提供了一些通过Internet互联主机之间通信的简单功能,目的是为了了解Socket编程的过程,程序源码参见随书发行的“利用Socket实现聊天程序”。
1.典型的函数调用时序图
Socket程序编写并不困难,关键在于理解好客户端和服务器之间的函数调用时序,面向连接的流式套接字的函数调用时序图如图10-4所示。
图10-4 流式套接字函数调用流程图
服务器端首先通过Socket创建套接字,接下来需要定义一个address结构,该结构中存储了本机的IP地址、程序通信端口以及通信域等信息。在使用WinSock编程时,由于Win-Sock只支持一种通信域,即网际域,因此该结构中的sin_family变量一般为AF_INET。定义好地址结构后,就可以将套接字和定义好的地址结构进行绑定,告诉操作系统所有发送给该端口的数据都由本程序处理。接下来就可以开始监听网络上的客户端连接。当客户端有连接请求时,通过accept函数接受客户的连接请求,并创建新的套接字单独与该连接客户通信,建立好连接之后就可以通过发送和接收函数来与客户端进行信息交互,同时accept函数可以继续接受其他客户端的连接请求。
客户端的时序相对简单得多,首先创建套接字,然后通过connect函数连接主机,con-nect函数的调用参数中有服务器的地址和端口信息,正确填写后就可以连接服务器;建立连接之后就可以通过发送和接收函数与服务器交换数据。
这里需要一提的是,在编程时服务器程序必须执行本地地址绑定操作,而客户端程序通常省略这一步,由系统分配默认的本地地址和端口号给相关套接字。也就是说在客户端无论是建立的流式套接字还是数据报套接字,在connect()和发送数据之前都可以省略bind()这一步,由系统自动绑定本地地址和空闲端口给相应的套接字。这样做的好处是简化代码、系统自动分配端口可以避免与已用端口的冲突。那么为什么服务器必须进行地址绑定呢?服务器是被访问的对象,客户端访问之前必须知道服务器程序的地址和端口,否则无法连接服务器。如果不对服务器建立的套接字进行地址绑定,而是由系统自动分配,那么需要通过其他的系统调用函数获得系统为这个套接字分配的地址和端口,这无疑增加了代码的复杂性。
2.代码分析
下面以服务器端程序为例说明Socket的编程方法和流程,程序中的关键代码都有相应的注释,和客户端程序类似,通过注释描述编程思路。(www.daowen.com)
服务器端程序的执行过程和时序图相同。首先,程序中要包含必要的头文件和库文件,并定义一些宏、结构和函数,如下所示。
下面介绍main函数的主要流程,这里只分析关键代码。为节省篇幅,省略了一些语句,格式作了紧凑安排,这种格式在实际编程中是很忌讳的。
下面介绍TCP服务线程函数的执行过程。这一部分实现了一个与客户端进行实时聊天的过程,函数功能较简单,下面只介绍TCP服务线程主要的函数流程。
Socket是十分强大的网络编程工具,它已经成为Linux和Windows环境下编写网络程序事实上的标准。Socket编程在网络模型中处于较高的位置,它为程序员隐藏了底层复杂的协议实现过程,通过提供简单、稳定的API接口函数,程序员就可以开发功能强大的程序。然而基于Socket编写的程序不能控制底层数据的访问,这就限制了Socket的某些应用,如网络监控等。相对Socket而言,下面要介绍的Winpcap则可以实现对底层原始数据帧的直接访问,程序员的可操作性更加强,但是编程稍微复杂一些。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。