第20章网络编程·随着Internet的逐渐普及,越来越多的软件项目应用涉及到网络。而Java似乎专门为网络设计的,它提供了很多方法供程序员使用,使大家能够很方便地开发网络应用软件。在本章中,将介绍Java网络编程的基础知识,以及网络编程的特点和方法。通过本章的学习,读者应该完成如下几个目标。·了解什么是协议,有哪些协议。·了解网络编程的模型。·熟练掌握使用Socket进行网络编程。北京源智天下科技有限公司1-1联系方式:网络编程基础·简单来看,网络编程的目标就是计算机之间相互通讯数据。JavaSDK提供了一系列API来完成这些工作,例如Socket。对于程序员来说,这些API被存放在java.net这个包里面,因此只要导入这个包就可以进行网络编程。北京源智天下科技有限公司1-2联系方式:协议·现在的Internet或Intranet大部分都是使用TCP/IP协议进行网络通信的,实际上TCP/IP协议是一组以TCP与IP协议为基础的相关协议的集合。·注意:该协议并不完全符合OSI的七层参考模型,而是采用的4层结构。·IP协议是TCP/IP协议族的核心,也是互连网络层中最重要的协议。其接收由更低层发来的数据包,并将该数据包发送到更高层,即TCP或UDP层;此外IP层也可以将从TCP或UDP层接收来的数据包传送到更低层。IP是面向无连接的数据报传送,所以IP协议将报文传送到目的主机后,无论传送正确与否都不进行检验、不会送确认以及不保证分组的正确顺序。北京源智天下科技有限公司1-3联系方式:·TCP协议位于传输层,其提供面向有连接的数据包传送服务,保证数据包能够被正确传送与接收,包括内容的校验与包的顺序,损坏的包可以被重传。要注意的是,由于提供的是有保证的数据传送服务,因此传送效率要比没有保证的服务低,一般适合工作在广域网中,对网络状况非常好的局域网不是很合算。当然,是否采用TCP也取决于具体的应用需求。北京源智天下科技有限公司1-4联系方式:网络编程模型·对于网络编程来说,目前主要有两种编程模型,分别是C/S结构和B/S结构。C/S结构是指客户机/服务器结构。所谓客户机/服务器结构,指的是在客户端需要安装客户端软件,由客户端软件负责与服务器端的数据通讯,将任务合理分配到客户端和服务器端来实现,降低了网络的负载开销。·B/S结构是指浏览器/服务器结构。客户端只需要安装有网页浏览器,不需要安装客户端软件,大部分逻辑事务处理在服务器端完成,客户端浏览器只完成少量的事务处理,减少了客户端的计算机负载,减轻了系统维护与升级的成本和工作量。在JAVA这样的跨平台语言出现之后,B/S架构管理软件更是方便、快捷、高效。北京源智天下科技有限公司1-5联系方式:网络传输协议·在前面已经讲解了TCP协议的知识,网络传输协议除了TCP协议外,还有UDP协议。UDP(UserDatagramProtocol)是用户数据报协议的英文缩写,UDP是不可靠的无连接数据报服务,它不需要像TCP那样建立连接,它有点类似电报的形式,直接发送,而不管接收端是否收到了数据,所以效率高,发送时速度快,但是不可靠。·UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址。UDP数据包在网络上传往目的地的路径是未知的,因此能否到达目的地,到达目的地的时间以及内容是否正确都是不能确定的。使用UDP无需要建立发送方和接收方的连接。而TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前首先要建立连接,所以在利用TCP协议传输的过程中增加了连接建立的时间。北京源智天下科技有限公司1-6联系方式:·使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。而TCP没有这方面的限制,一旦连接建立起来,双方的Socket就可以按统一的格式传输大量的数据。再次需要强调的是,UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。而TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。·提示:网络编程的目的是指通过网络协议与其他计算机进行通信。网络编程中主要有两个的问题:一是如何准确地定位网络上一台或多台主机,二是如何找到主机后可靠高效地进行数据传输北京源智天下科技有限公司1-7联系方式:端口和套接字·端口被规定为一个在0~65535之间的整数。Http服务一般使用80端口,Ftp使用的是21端口,那么客户必须通过80端口才能连接到服务器的Http服务,而通过21端口,才能连接到服务器的Ftp服务器上。·在所有的端口中1~1023之间已经被系统所占用了,因此在定义自己的端口时,不能使用这一段的端口号,而应该使用1024~65535之间的任意端口号,以免发生端口冲突。·网络程序中的套接字用来将应用程序与端口连接起来,套接字是一个软件实现,也是一个假想的装置。在Java中,将套接字抽象化为类,所以程序只需创建Socket类的对象,就可以使用套接字。那么Java是如何实现数据传递的呢?答案是使用Socket的流对象进行数据传输,Sokcet类中有输入和输出流。使用Socket进行的通信都称为Socket通信。将编写的Socket类,用在Socket通信程序中,这就称为Socket网络程序设计。北京源智天下科技有限公司1-8联系方式:协议的网络编程·通过前面一节的介绍,读者已经对网络编程基础的知识有了一个简单的介绍。本节将继续向读者介绍如何利用Java进行基于TCPSocket(套接字)连接的网络应用的开发。TCP/IP是用于计算机通信的一组协议,它包括TCP、UDP等许多协议,这些协议一起称为TCP/IP协议。北京源智天下科技有限公司1-9联系方式:套接字·Socket套接字是基于TCP/IP协议的编程接口,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过Socket套接字向网络发出请求或者应答网络请求。·Socket有两种主要的操作方式,包括面向连接的和无连接的。面向连接的socket操作就像人们打电话,必须先拨号码,建立一个连接,然后再对话。数据包在到达接收端时的顺序与它们出发时的顺序时一样,就像一个人在电话中对另一个人说话一样,每一个字到达另一端的时候与它出发时的顺序一样。·无连接的socket操作就像是邮递员送信,邮递员只负责把信送出,至于何时发出,最后能不能到达收信人手中不能保证,无连接的socket操作也一样,负责发出,但不保证数据包的传输质量,数据包到达目的地的顺序可能与出发时的顺序不一样。北京源智天下科技有限公司1-10联系方式:类·Java中的网络编程是通过ServerSocket类和Socket类结合使用来完成的。这里首先来讲解一下ServerSocket类,ServerSocket是应用在服务器端的类。在服务器端,由ServerSocket类负责实现服务器套接字。ServerSocket类位于java.net包中。由ServerSocket对象监听指定的端口,端口可以任意指定,但是要注意1024以下的端口通常属于系统保留端口,因此不可以随便使用,应该使用大于1024的端口号,开始监听后,服务器就等待客户端连接请求,客户端连接后,会话开始;在完成会话后,关闭连接。北京源智天下科技有限公司1-11联系方式:·注意:同一台主机上的同一端口号只能分配给一个特定的ServerSocket对象,不能两个ServerSocket对象监听同一个端口。端口号的理论范围为0~65535,但前1024个中的大部分已经分配给了特定的应用协议,所以不能选用。北京源智天下科技有限公司1-12联系方式:·在ServerSocket类中有几个非常常用的方法。首先要讲的就是accept方法,使用该方法接收客户端的连接请求,并将与客户端的连接封装成一个Socket对象返回。·注意:此方法为阻塞方法,在没有接收到任何连接请求前调用此方法的线程将一直阻塞等待,直到接收到连接请求后此方法才返回,调用此方法的线程才继续运行。·除了accept方法外还有一个close方法来关闭ServerSocket对象。使用getLocalPort方法来获取设置的端口号。北京源智天下科技有限公司1-13联系方式:类·Socket类表示套接字。使用Socket时,需要指定待连接服务器的IP地址及端口号。客户机创建了Socket对象后,将马上向指定的IP地址及端口发起请求且尝试连接。于是,服务器套接字就会创建新的套接字对象,使其与客户端套接字连接起来。一旦服务器套接字与客户端套接字成功连接后,就可以获取套接字的输入输出流,彼此进行数据交换。Socket类一共有9个构造器,表列出了其中常用的两个。北京源智天下科技有限公司1-14联系方式:·Socket类中同样具有一些方法。其中getPort方法和getLocalPort方法分别是获取连接的远程端口和使用的本地端口。getInputStream方法和getOutputStream方法分别是获取Socket对象的输入流和输出流,这两个方法是经常被使用到的。·注意:close方法虽然是很简单的,表示关闭Socket对象。但是该方法在程序中是必须有的,这是一个非常好的网络编程习惯。北京源智天下科技有限公司1-15联系方式:架构实例·C/S架构的网络编程程序是由服务器端和客户端所组成的,在开发时一定要先开发服务器端的程序,再来开发客户端的程序。·············1-1608091011121314151617象181920intcount=0;//声明用来计数的int局部变量try{//创建绑定到9876端口的ServerSocket对象ServerSocketserver=newServerSocket(9876);System.out.println(服务器对9876端口正在进行监听);//服务器循环接收客户端的请求,为不同的客户端提供服务while(true){//接收客户端的连接请求,若有连接请求返回连接对应的Socket对Socketsc=server.accept();//获取当前连接的输入流,并使用处理流进行封装DataInputStreamdin=newDataInputStream(sc.getInputStream());北京源智天下科技有限公司联系方式:··2122//获取当前连接的输出流,并使用处理流进行封装DataOutputStreamdout=newDataOutputStream(sc.getOutputStream());············1-17232425262728293031323334//打印客户端的信息System.out.println(这是第+(++count)+个客户访问);System.out.println(客户端IP地址:+sc.getInetAddress());System.out.println(本