单元21 网络编程.docx
网络聊天程序设计单元21网络编程单元目标 理解并掌握网络通信的概念和方法 掌握网络通信中TCP/IP协议的编程原理 理解并掌握Socket/ServerSocket类的使用方法 掌握网络通信中UDP协议的编程原理 理解并掌握URL类的使用方法 理解并掌握DatagramSocket/DatagramPacket类的使用方法 学习任务011 .任务描述网络聊天系统利用Internet的资源优势和技术优势,为人们提供了一种方便 快捷的信息交流和沟通方式。本次任务要运用套接字实现一个多人网络聊天程 序。任务要求如下: 在C/S (客户端/服务器)模式下运行。 服务器端负责监听和转发客户端发送的消息。 实现聊天记录的保存和查看。2 .运行结果知识准备f 21. 1网络通信与网络协议基础V'网络聊天程序设计计算机网络是利用通讯设备和线路将地理位置不同的、功能独立的多个计算 机系统互连起来,以功能完善的网络软件(即网络通信协议、信息交换方式及网 络操作系统等)实现网络中资源共享和信息传递的系统。计算机网络通常由三个部分组成,分别是资源子网、通信子网和通信协议。 所谓通信子网就是计算机网络中负责数据通信的部分;资源子网是计算机网络中 面向用户的部分,负责全网络面向应用的数据处理工作;而通信双方必须共同遵 守的规则和约定就称为通信协议,它的存在与否是计算机网络与一般计算机互连 系统的根本区别。系统。任务要求如下: 客户端采用UDP协议与服务器连接 客户端可以设置服务器地址与端口 服务器可以维护客户端个人信息 服务器可以记录客户端状态信息2.运行结果知识准备_r遨' X无连接网络聊天程序设计21.4. 于UDP的网络编程原理用户数据包协议(UDP)是OSI参考模型中一种无连接的传输层协议,IETF RFC 768是UDP的正式规范。如图5-19所示,UDP在传输数据之前,客户端 和服务器端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并 尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅受应用程序 生成数据的速度、计算机性能和传输带宽的限制;在接收端,UDP把每个消息 段放在队列中,应用程序每次从队列中读一个消息段。由于传输数据不建立连接, 因此也就不需要维护连接状态,包括收发状态等,因此一个服务端可同时向多个 客户端传输相同的消息、。图5-19UDP通信方式【小提示】TCP协议与UDP协议的区别:TCP提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面 向连接、端到端进行数据包通信,可以保证数据通信的可靠性。但是,由于传输过程需要 进行三次握手,所以传输速度相对较慢。而UDP则不为IP提供可靠性、流控或差错恢复功 能,因此,传输速度较快。一般来说,TCP对应的是可靠性要求较高的应用,而UDP对应的则是可靠性要求较低的 应用。TCP支持的应用协议主要有:Telnet. FTP、SMTP等;UDP支持的应用层协议主要有: NFS (网络文件系统)、SNMP (简单网络管理协议)、DNS (主域名称系统)、TFTP (通用文件 传输协议)等。UDP网络编程相关类的使用21.5. 1 DatagramPacket 类Datagram Packet类表示数据报包,起到数据容器的作用。数据报包用来实 现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一 台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按 不同的顺序到达。不对包投递做出保证。DatagramPacket构造方法如下:DatagramPacket(byte data, int size)构造 DatagramPacket,用来接收长 度为length的数据包。DatagramPacket(byte data, int size, InetAddress I, int port)构造数据报 包,用来将长度为length的包发送到指定主机上的指定端口号21.6. 2 DatagramSocket 类Datagramsocket类表示用来发送和接收数据报包的套接字,用于发送或接 收DatagramPacketo数据报套接字是包投递服务的发送或接收点。每个在数据 报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机 器的多个包可能选择不同的路由,也可能按不同的顺序到达。在 DatagramSocket上总是启用UDP广播发送。为了接收广播包,应该将 DatagramSocket绑定到通配符地址。在某些实现中,将DatagramSocket绑 定到一个更加具体的地址时广播包也可以被接收。DatagramSocket s = new DatagramSocket(null);等价于:DatagramSocket s = new DatagramSocket(8888);这两个例子都能创建能够在UDP 8888端口上接收DatagramSocket。DatagramSocket 构造方法:DatagramSocket()构造数据报套接字并将其绑定到本地主机上任何可用的 端口。DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指 定端口。其他常用方法:void send(DatagramPacket d)从此套接字发送数据报包。void receive(DatagramPacket p)从此套接字接收数据报包。void close()关闭此数据报套接字。【实例5-18】演示通过UDP协议通信的过程。【、源代码5-23】要求:Datagramserver类接收用户从控制台输入的字符串,并将字符串发 送给Datagramclient。Datagramclient接收并显示收到的字符串。当用户输入 end时,DatagramServer发送完就退出运行。Datagramclient接收到end字 符串后也立刻退出运行。服务器端关键代码如下:D atag r a m S e rve r 类 省略定 义byte buffer = new byte1024;71无连接网络聊天程序设计ds = new DatagramSocket(SERVER_PORT);while(true)break;客户关键代码如下:/Datagramclient 类省略定义ds = new DatagramSocket(CLIENT_PORT);无连接网络聊天程序设计while(true)break;服务器端程序运行结果如下:服务器正在等待输入HelloEnd服务器退出运行客户端程序运行结果如下:客户机正在等待服务器发送数据HelloEnd客户机退出运行网络编程实现广播Java网络编程还可以实现广播功能的类有:MulticastSocket和Datagram Packet o发送广播消息的程序代码如下:MulticastSocket s = new MulticastSocket(6789); / 构造广播对象加入广播组/创建数据包”c无连接网络聊天程序设计String msg = "Hello11;'Datagram Packet hi = new Datagram Packet/设置发送范围、发送s. setTimeToLive(l);接收广播消息的程序代码如下:MulticastSocket s = new MulticastSocket(6789);/ 构造广播对象/加入广播组/准备缓冲区”无连接网络聊天程序设计byte buf = new byte1OOO;/接收数据离开分组任务实施1 .实现思路创建一个类UdpDialogFrame,既作为信息发送端,又作为信息接收端。程 序运行时,显示本机IP地址和所用端口号。允许用户输入信息发送目标的IP地 址和端口号。在线程体中接收数据包,在TextListener接口的文本变化事件处理 方法中发送数据包。 定义类 UdpDialogFrame 继承 Frame 实现TextListener, Runnable 接 口。 在UdpDialogFrame类的构造方法中构造窗口界面,启动数据接收线程 在textValueChanged方法中发送信息 在run方法中接收并显示信息 仓1J建主类UdpDemo,仓U建UdpDialogFrame类对象2 .程序代码/省略窗体控件初始化代码不时无连接网络聊天程序设计I-public UdpDialogFrame() super("随心聊)init(); /调用窗体控件初始化方法/窗口事件处理addWindowListener(new WindowAdapter() /关闭窗口事件处理public void windowClosing(WindowEvent e) );m_thRecieve = newThread(this);/文本变化事件处理public void textValueChanged(TextEvent e) 省略异常处理Datagram Packet pak = new Datagram Packet 省略异常处理DatagramSocket skt = new DatagramSocket(); )/接收线程处理public void run() DatagramSocket skt = new DatagramSocket(980);byte data = new byte1O24;while (true) 省略异常处理String s = new String(data); else )datafi = 0;省略调用任务拓展Java程序也可以象浏览器那样获取互联网资源。URL指向Internet上的 资源文件。URL的组成部分依次包括协议、IP地址或主机名、端口号、实际文 件路径。如一个URL对象 代表一个统一资源定位符,它是指向互联网“资源”的指针。 资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据 库或搜索引擎的查询。URL类提供API来访问Internet上的信息。URL类的构造方法:URL(String urlname)根据String表示形式创建URL对象.URL(String protocol, String hostname, int port, String path)根据指定 protocol> host> port 号和 file 创建 URL 对象.URL(String protocol, String hostname, String path)根据指定的 protocol 名称、host名称和file名称创建URL.【实例5-19】演示URL类中几个方法的使用。【'、源代码5-24】说明:如果URL格式不正确,程序会出MaHormedURLException异常。"/省略异常处理););););程序运行结果如下:厂匚无连接网络聊天程序设计URL中的主机是:'使用的协议是:http使用的端口是:80【实例5-201演示通过Java程序调用百度搜索引擎获取搜索的网页结果。UQ源代码】/省略变量定义String makellrl(String keywords,int nPage)rt += keywords;rt += H&pn=H;=rt += nPage*10;无连接网络聊天程序设计rt += H&cl=3n;return rt;String searchOnePage(String keywords,int nPage)(String content =URL url = null;URLConnection conn = null;String nextLine =StringTokenizer tokenizer = null;Collection urlCollection = new ArrayList();url = new URL(makellrl(keyWords3nPage);省略异常处理BufferedReader reader = new BufferedReader(content += nextLine; content += Hnn;)return content;省略调用【思考】网络游戏中,不同玩家的网速、计算机运行速度都不相同,如何实现所有玩家看到的 游戏状态是一致的?任务实训1 .实训目的熟练数据报的发送和接收;能使用DatagramPacket类创建数据报对象并在应用程序之间建立传送数据报的通讯连接。2 .实训内容畲无连接网络聊天程序设计用UDP协议实现聊天程序。21网络体系结构指的是通信系统的整体设计,它的目的是为网络硬件、软件、 协议、存取控制和拓扑提供标准。现在广泛采用的是开放系统互连参考模型 OSI(Open System Interconnection),如图5-16所示,它是用物理层、数据链路 层、网络层、传输层、会话层、表示层和应用层七个层次描述网络的结构。网络 体系结构的优劣将直接影响网络的性能。图5-16开放系统互连参考模型计算机网络的协议所谓协议(Protocol)就是对数据格式和计算机之间交换数据时必须遵守的规 则的正式描述。依据网络的不同通常使用Ethernet(以太网)、NetBEUk IPX/SPX 以及TCP/IP协议。日hemet是总线型协议中最常见的网络底层协议,安装方 便且造价便宜。而NetBEUI可以说是专为小型局域网设计的网络协议。对那些 无需跨路由器与大型主机通信的小型局域网,安装NetBEUI协议就足够了,但 假如需要路由到另外的局域网,就必须安装IPX/SPX或TCP/IP协议。TCP/IP(传 输控制协议/网间协议)是开放系统互连协议中最早的协议之一,也是目前最完全 和应用最广的协议,能实现各种不同计算机平台之间的连接、交流和通信。1 .传输控制协议TCP传输控制协议(TCP)属于TCP/IP协议族的传输层,提供可靠的数据传 输服务。TCP是一种面向连接的传输层协议,意味着该协议准备发送数据时, 通信之间必须建立起一个逻辑上的连接。TCP协议位于IP协议的上层,通过提 供校验和、流控制及序列信息弥补IP协议可靠性的缺陷。2 . IP协议IP是英文Internet Protocol (网络之间互连的协议)的缩写,中文简称为“网 协”,也就是为计算机网络相互连接进行通信而设计的协议。数据帧的IP部分被称为一个IP数据报,IP数据报如同数据的封面,包含了 路由器在子网中传输数据所必须的信息。IP协议是一种不可靠的、无连接的协议。然而,TCP/IP协议族中更高层协 议可使用IP信息确保数据包按正确的地址进行传输。3 .用户数据报协议UDP用户数据报协议UDP (User Datagram Protocol),位于TCP/IP协议族的传输层。不同于TCP的是,它是一种无连接的传输服务,它不保证数据包以正确的顺序 接收。4 .超文本传输协议HTTP超文本传输协议HTTP是TCP/IP协议族的应用层协议。客户和WWW服 务器之间的交互规则就是HTTPO5 .文件传输协议FTP文件传输协议FTP (File Transfer Protocol)是应用较广泛的网络协议之一, 也是是Internet上最早使用的文件传输程序,它定义了在两台机器间传输文件 的规程。FTP协议可以支持文件在网络上不同机器之间的来回拷贝。6 1.2基于TCP/IP的网络编程原理Java网络编程可以使用不同的通信协议,本任务使用TCP/IP协议进行网络 编程。IP地址用于区分网络上不同的主机。端口用于区分同一机器上不同的通信程序, 编号0-1023的端口为系统预定义使用,编号1024-65535的端口留给一般应用 程序使用。套接字(Socket)是Internet通信的端点,与主机地址和端口号相 关联。客户端和服务器通过套接字建立连接和进行通信。在TCP/IP协议中,TCP提供可靠的连接服务,采用三次握手建立一个连接。 具体过程如图5-17所示:第一次握手:客户端请求连接,发送SYN包到服务器,并进入SYN_SEND 状态,等待服务器确认。第二次握手:服务器收到SYN包,必须确认客户的SYN,同时自己也发送 一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。第三次握手:客户端收到服务器的SYN + ACK包,向服务器发送确认包 ACK,此包发送完毕后,客户端和服务器进入ESTABLISHED状态,完成三次 握手。完成三次握手后,客户端与服务器开始传送数据。图5-17 TCP协议三次握手过程分析7 1.3 TCP/IP网络编程相关类.1 Socket 类Socket类用于客户端程序,当客户端与服务端通讯的时候,客户程序会在客户端创建一个Socket对象,建立服务器和客户端之间的连接。Socket类的常用构造方法:Socket(String hostName, int port)创建一个流套接字并将其连接到指定主 机上的指定端口号。Socket(lnetAddress a, int port)创建一个流套接字并将其连接到指定IP地 址的指定端口号。Socket类的其他常用方法:InetAddress getlnetAddress()返回套接字连接的地址。int getPort()返回此套接字连接到的远程端口。int getLocalPort()返回此套接字绑定到的本地端口。Inputstream getlnputStream()返回此套接字的输入流。Outputstream getOutputStream()返回此套接字的输出流。.2 ServerSocket 类Serversocket类用于服务端程序,服务端需要创建ServerSocket对象监听 特定端口,接收客户连接请求,并基于该请求执行某些操作,然后向请求者返回 结果。ServerSocket类的常用构造方法:ServerSocket(int port)创建绑定到特定端口的服务器套接字。ServerSocket(int port, int maxqu)创建绑定到特定端口的服务器套接字, maxqu为队列的最大长度。ServerSocket类的其他常用方法:accept。方法用于等待客户端触发通信,会阻塞线程,等待直到有客户连接 才返回。close。方法用于关闭服务器端建立的套接字。.3 Socket通信方式利用Socket方式进行数据通信与传输的整个过程如图5-18所示:Socket 对象代表主叫方,ServerSocket对象代表被叫方,执行accept。方法表示同意 建立连接。连接一旦建立,会自动创建一个输入流和一个输出流,通过这两个流 可以实现数据的发送。图5-18 Socket通信示意图【实例5-15演示如何创建服务端程序。【、源代码5-20要求:服务器启动后等待客户端连接,有客户端连接时,执行accept。方法 返回一个Socket对象。通过此Socket对象可获得输入流和输出流。通过输入 流,可获取客户端传入的数据。如果获取的数据为“JAVA”,则通过输出流向客 户端传送“有效口令”四个字,否则向客户端传送“无效口令”四个字。 /省略类的定义和异常处理ServerSocket ss = new ServerSocket(4001);Buffered Reader b = new BufferedReader(new lnputStreamReader(sy:网络聊天程序设计String response;response = "有效口 令”;)elseresponse = "无效口 令”;)Printstream p = new PrintStream();省略调用过程【实例5-16】演示如何创建客户端程序。【、源代码5-21】要求:通过使用相同的端口号来连接例5-21的服务器程序。本例的服务端 与客户端程序应当运行在同一台主机上,因为程序中的Socket对象是通过 localhost创建的。该客户端程序从控制台读入用户输入信息,将其发送给服务 器,然后读取并显示服务器返回的信息。省略类的定义和异常处理网络聊天程序设计Socket so = new Socket("localhostn3 4001);BufferedReader b1 = new BufferedReader (newBufferedReader b2 = new BufferedReader省略调用过程任务实施1 .实现思路综合运用流、线程和Socket技术实现本任务中的网络聊天程序。把服务端 程序定义为ChatServer,先于客户端程序运行,监听并接受多个客户端的连接。 把客户端程序定义为ChatClient,负责将用户的输入信息发送到服务端。服务端 程序接受客户信息并将其转发给其他客户端。(1)定义Client类实现Runnable接口,作为客户端代理,目的是在服务器 端为每个客户端创建一个单独的通信线程(2)定义ChatServer类,等待客户的连接请求,用列表clients保存客户端 代理,每次和一个客户端建立连接,创建一个代理对象放入列表clients中(3)定义ChatClient类继承JFrame,实现客户端界面,与服务器建立连接, 接收用户输入发送给服务器并显示服务器发送来的信息2 .程序代码Client类的关键代码如下:省略类与成员的定义public Client(Socket s,int client_no) /省略成员初始化与异常处理语句/初始化流对象public void send(String str) 用于发送消息给客户端 try ( catch (lOException e) /移除退出的对象public void run() /省略异常处理while (cont) String str /阻塞式方式String prefix = "Client'+ client_no + I”; str = prefix + str;/获取客户端代理if(log!= null && c = this) 省略异常处理保存记录服务器端的关键代码如下:省略类的声明List<Client> clients = new ArrayListvClient>(); /用于存储客户端对象 public ChatServer() 省略异常处理 )public void start() 省略异常处理、曲:8网络聊天程序设计ss = new ServerSocket(8888);'stat = true;while (stat) /每建立一个客户端,就创建一个客户端对象,启动一个线程Client c = new Client(s,maxClientNo+);newThread(c).start();客户端的关键代码如下:Thread tRecv = new Thread(new RecvThread();public static void main(String args) new ChatClient().launchFrame();y C'网络聊天程序设计)public void launchFrame() 省略窗体布局设置代码public void windowClosing(WindowEvent e) disconnect(););省略控件设置代码connect();)public void connect() 省略异常处理代码s为局部变量etOutputStream();)public void disconnect() /省略异常处理)private class TfListent implements ActionListener public void actionPerformed(ActionEvent e) String s省略异常处理)private class RecvThread implements Runnable public void run() while (cont) 省略异常处理任务拓展Internet上的主机有两种表示地址的方式:域名和IP地址。有时候需要通过 域名来查找它对应的IP地址,有时候又需要通过没有公共的构造方法,程序员 只能利用该类的一些静态方法来获取对象实例,然后再通过这些对象实例来对IP 地址或主机名进行处理。该类常用的一些方法如下:pulic static InetAddress getByName(String hostname)根据给定的主机名仓 建一个InetAddress对象,可用来查找该主机的IP地址。public static InetAddress getByAddress(byte addr)根据给定的 IP 地址创 建一个InetAddress对象,可用来查找该IP对应的主机名。public String getHostAddress()获取 IP 地址。public String getHostName()获取主机名。下面通过两个实际的例子来说明它的使用方法。【实例5-17】演示InetAddress类的用法。3源代码5-22要求:获取并显示了本机和新浪网的IP地址。运行此程序,要求电脑能够 联通互联网,否则需要给新浪网那行代码加上注释,不然会出异常的。省略类的定义与异常处理InetAddress add = ;»yj网络聊天程序设计程序运行结果如下:本主机新浪网的地址是任务实训1 .实训目的 掌握创建基于TCP有连接的网络应用程序; 掌握创建服务端套接字的方法; 掌握创建客户端套接字的方法; 掌握从连接中读取信息; 掌握向连接中写入信息。2 .实训内容网络聊天程序设计用Socket实现客户和服务器交互的典型C/S结构的聊天程序。学习任务021.任务描述为了进一步掌握网络编程技术,本次任务要基于UDP实现一个局域网聊天