第 12章 Java的网络编程
Java最初是作为一种网络编程语言出现的,它能够使用网络上的各种资源和数据与服务器建立各种传输通道,将自己的数据传送到网络的各个地方。你可以用 Java很轻松地完成这些工作,因为
Java类库提供了很强大的网络功能。
本章要点
网络基础知识
Java网络编程概述
Java网络类和接口
基于 URL的网络编程
基于 Socket的网络编程
数据报通信的应用
TCP/IP( Transmission Control
Protocol传输控制协议 /Internet
Protocol网间协议)是 Internet的主要协议,定义了计算机和外设进行通信所使用的规则。 TCP/IP网络参考模型包括五个层次:应用层、传输层、网络层、链路层、物理层。
ISO/OSI网络参考模型则包括七个层次:应用层,表示层、会话层,
传输层、网络层、链路层、物理层。
12.1 网络基础知识物理层大多数基于 Internet的应用程序被看作 TCP/IP网络的最上层 ——应用层,如,ftp,http,smtp,pop3,telnet,nntp等。
网络层 对 TCP/IP网络中的硬件资源进行标识。连接到
TCP/IP网络中的每台计算机(或其他设备)都有唯一的地址,
这就是 IP地址 。 IP地址实质上是一个 32位的整数,通常以
,%d.%d.%d.%d”的形式表示,每个 d是一个 8位整数。
在 TCP/IP网络中,不同的机器之间进行通信时,数据的传输是由 传输层 控制的,这包括数据要发往的目标机器及应用程序、数据的质量控制等。 TCP/IP网络中最常用的传输协议就是 TCP( Transport Control Protocol)和 UDP( User
Datagram Protocol)。
12.1 网络基础知识一台机器通常只通过一条链路连接到网络上,即它只有一个 IP地址,但一台机器中往往有很多应用程序需要进行网络通信,如何区分呢?这就要靠 网络端口号 ( port)了。
端口号是一个标记机器的 逻辑通信信道 的正整数,端口号不是物理实体。 IP地址和端口号组成了所谓的 Socket,Socket
是网络上运行的程序之间双向通信链路的最后终结点,它是
TCP和 UDP的基础。
网络服务
http
ftp
其他服务
23
telnet
端口
21
80客户程序 Socket
IP,portIP与端口号组合而得出的 Socket,
可以完全分辨
Internet上运行的程序。
12.1 网络基础知识端口号是用一个 16位的整数来表达的,其范围为 0~ 65535,其中 0~ 1023为系统所保留,专门给那些通用的服务( well-known services),如
http服务的端口号为 80,telnet服务的端口号为 21,
ftp服务的端口为 23,… 因此,当我们编写通信程序时,应选择一个大于 1023的数作为端口号,以免发生冲突。
12.1 网络基础知识传输层通常以 TCP和 UDP协议来控制 端点到端点 的通信。用于通信的端点是由 Socket来定义的,Socket是由 IP
地址和端口号组成的。
传输控制协议( TCP)是在端点与端点之间建立 持续的连接 而进行通信。建立连接后,发送端将发送的数据印记了序列号和错误检测代码,并以字节流的方式发送出去;
接收端则对数据进行错误检查并按序列顺序将数据整理好,
数据在需要时可以重新发送,因此整个字节流到达接收端时完好无缺。这与 两个人打电话 的情形是相似的。
TCP协议具有可靠性和有序性,并且以 字节流 的方式发送数据,它通常被称为 流通信协议 。
12.1 网络基础知识与 TCP协议不同,用户数据报协议( UDP)则是一种 无连接 的传输协议。利用 UDP协议进行数据传输时,首先需要将要传输的数据定义成数据报( Datagram),在数据报中指明数据所要达到的端点( Socket,主机地址和端口号),然后再将数据报发送出去。这种传输方式是无序的,也不能确保绝对的安全可靠,但它很简单也具有比较高的效率,这与通过 邮局发送邮件 的情形非常相似。
12.1 网络基础知识
12.1 网络基础知识
TCP协议和 UDP协议各有各的用处。当对所传输的数据具有时序性和可靠性等要求时,应使用
TCP协议;当传输的数据比较简单、对时序等无要求时,UDP协议能发挥更好的作用,如 ping、
发送时间数据等。
12.1 网络基础知识通过 InetAddress,可以获取本机的 IP地址:
public class getLocalHostTest
{
public static void main()
{
InetAddress myIP = null;
try{
myIP = InetAddress.getLocalHost();
}catch(UnknownHostException e){}
System.out.println(myIP);
}
}
3、使用 InetAddress
getLocalHostTest.java
URL是统一资源定位符( Uniform Resource
Locator)的简称,它表示 Internet上某一资源的地址。 Internet上的资源包括 HTML文件、图象文件、
声音文件、动画文件以及其他任何内容(并不完全是文件,也可以是一个对数据库的查询等)。
通过 URL,就可以访问 Internet。浏览器或其他程序通过解析给定的 URL就可以在网络上查找相应的文件或其他资源。
12.1 网络基础知识一个 URL包括两部分内容,协议名称和资源名称,中间用冒号隔开:
Protocol:resourceName 如,http://gis.pku.edu.cn
协议名称指的是获取资源时所使用的应用层协议,如
http,ftp,file等;资源名称则是资源的完整地址,包括主机名、端口号、文件名或文件内部的一个应用。当然,并不是所有的 URL都必须包含这些内容。
http://www.pku.edu.cn
http://gis.pku.edu.cn/javaCourse/index.html
ftp://gis.pku.edu.cn/javaCourse/Techdoc/ch1.ppt
http://www.abc.com:8080/java/network.html#UDP
12.1 网络基础知识一般计算机操作系统或软硬件厂商会提供已完成的底层网络应用模块供用户使用,但在用户程序有特殊需要时,编程人员也可以自己编制底层网络应用程序来实现网上的底层通信,如具体实现网络层或传输层的某些协议。由于 Java中提供了支持这些网络协议的专用类库,所以使用
Java语言可以编制负责的底层网络应用。
利用 Java语言还可以编写高层网络应用。现在已经存在用 Java编写的复杂大型的商用分布系统,其功能包括网络上的公布式运算、分布式管理、
分布式数据库应用等。这类应用一般比较复杂,通常依附在一个已经存在的综合性网络上作为该网络服务的一部分,Internet,Intranet和
Extranet就是目前较常见的综合性网络。它们上面可以开通多种由高层网络应用构成的服务,如网上购物、网上教学、网上银行、电子商务等。
由于这些综合性网络的普及和其标准化程度的提高,因此用 Java编写的高级网络应用通常都工作于它们所规定的环境中。
12.2 Java网络编程概述以上是按照工作层次的划分不同的 Java网络应用。事实上,在同一层次中根据功能的不同还可以将应用细分为不同的部分,这是由网络计算结构的分布式特点所决定的。在网络计算结构中,功能不同的机器其地位和扮演的角色也不同,其上运行的应用也不同,如我们前面介绍过的 Client和 Server,Server是提供服务的程序或运行这样程序的计算机。 Client是请示服务的程序或运行这样程序的计算机;
一个完整的网络应用系统应该由 Server端的应用程序和 Client端的应用程序共同组成,并保证它们能够协同工作。所以在开发网络应用程序之前,应该先进行内容和分工的划分,根据应用的体系结构将整个任务划分为 Server端的应用,Client端的应用和其他需要的部分,明确各部分各自的功能后才能再进行更进一步的工作。
Client端的应用和 Server端的应用由于工作环境和任务性质的不同,有着各自不同的特点,在开发设计时应给予充分的考虑。例如 Server端程序一般工作在高性能、
大容量、高运算速度的机器上,一个 Server被设计成能响应多个 Client的服务请求;
而 Client端的应用由于直接与用户打交道,且运行的环境差异性很大以及通常性能不高等原因,所以一般多包含精美的画面、活泼的形式和方便的图形用户界面交互功能,而不进行关键性的数据或事务处理。在开发一个具体的网络应用之前,
了解 Client和 Server之间的这些差别是很有必要的。
12.2 Java网络编程概述上述的 Client/Server体系结构实际上是网络计算结构中比较基本的结构。
目前,随着 Internet的迅速普及和推广,出现了更加复杂的网络计算结构,
如 Client/Web Sever/Application Server,Browser/Web Server等,采用这些计算结构将把网络应用划分为分工更细的部分。一个 Client程序需要能够工作在不同的 Client计算机上,如果这些机器的软硬件环境不同,
Client程序的跨平台功能就是必不可少的了。同样,对于 Server来说,跨平台功能可以提高网络应用的普适性,使之能工作在更广泛的范围里,
从这个意义上来说,Java是适合于编写网络应用的语言。另外 Java的平台无关特性还大大简化了 Java应用的升级和维护工作,进一步巩固了
Java网络计算工具的地位。
12.2 Java网络编程概述
Java中有关网络方面的功能都定义在 java.net程序包中。 Java所提供的网络功能可大致分为三大类:
( 1) URL类和 URLConnection类这是三大类功能中最高级的一种。通过 URL的网络资源表达方式,很容易确定网络上数据的位置。利用 URL的表示和建立,Java
程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端。
( 2) Socket类,即套接字,可以想像成两个不同的程序通过网络的通道,而这是传统网络程序中最常用的方法。一般在 TCP/IP网络协议下的客户服务器软件采用 Socket作为交互的方式。
( 3) Datagram类,是这些功能中最低级的一种。其他网络数据传送方式,都假想在程序执行时,建立一条安全稳定的通道。但是以 Datagram的方式传送数据时,
只是把数据的目的地记录在数据包中,然后就直接放在网络上进行传输,系统不保证数据一定能够安全送到,也不能确定什么时候可以送到。也就是说,
Datagram不能保证传送质量。
另外,InetAddress类也是经常应用的类,它可以用于标识网络上的硬件资源。它提供了一系列描述、获取及使用网络资源的方法。每个 InetAddress对象都包含 IP
地址、主机号等信息。 InetAddress类没有构造函数,因此不能用 new来构造
InetAddress实例。通常是用它提供的静态方法来获取。
12.3 Java网络类和接口
12.4 基于 URL的网络编程在 java.net包中,提供了类 URL来表示 URL。类 URL提供了很多构造方法来生成一个 URL对象:
public URL(String spec)
public URL(URL context,String spec)
public URL(String protocol,String host,String file)
public URL(String protocol,String host,int port,String file)
以下是一些具体的构造实例:
URL url1 = new URL(“http://gis.pku.edu.cn/map/index.html”);
URL base = new URL(“http://gis.pku.edu.cn”);
URL url2 = new URL(base,“mywork1.html”);
URL url3 = new URL(base,“mywork2.html”);
URL url4 = new URL(“http”,“gis.pku.edu.cn”,“/~lyw/test.html”);
URL url5 = new URL(“http”,“www.abc.com”,8080,“/java/network.html”);
另外还有两种稍微复杂些的构造方法(参见 JDK文档)。
当创建 URL时发生错误,系统会产生例外
MalformedURLException,这是非运行时例外,必须在程序中捕获处理。
URL url1,url2,url3;
try{
url1 = new URL(“file:/D:/image/example.gif”);
url2 = new URL(“http://gis.pku.edu.cn/map/”);
url3 = new URL(url2,“test.gif”);
}catch(MalformedURLException e)
{
DisplayErrorMessage();
}
12.4 基于 URL的网络编程一个 URL对象生成后,其 属性是不能被改变 的( 与
String对象相似 ),但可以通过它给定的方法来获取这些属性:
public String getProtocol():获取该 URL的协议名
public String getHost(),获取该 URL的主机名
public String getPort(),获取该 URL的端口号
public String getPath(),获取该 URL的文件路径
public String getFile(),获取该 URL的文件名
public String getRef(),获取该 URL在文件中的相对位置
public String getQuery(),获取该 URL的查询名
ParseURL.java
12.4 基于 URL的网络编程通过 URL类提供的方法 openStream(),就可以读取一个 URL对象所指定的资源。
public final InputStream openStream()
方法 openStream()与指定的 URL建立连接并返回一个 InputStream对象,将 URL位置的资源转成一个输入数据流。通过这个 InputStream对象,就可以读取资源中的数据。
URL Java 程序
InputStream
12.4 基于 URL的网络编程 —读取网络资源
import java.net.*;
import java.io.*;
public class URLReader
{
public static void main (String args[])
{
try{
URL gis = new URL("http://gis.pku.edu.cn/test.htm");
BufferedReader in = new BufferedReader(
new InputStreamReader( gis.openStream() ) );
String line;
while( (line = in.readLine()) != null )
{
System.out.println(line);
}
in.close();
}catch(Exception e){
System.out.println(e);
}
}
}
12.4 基于 URL的网络编程 —读取网络资源示例
12.4 基于 URL的网络编程
——URL和 InetAddress的联合使用
Applet中的网络通信需要将 URL和 InetAddress联合使用来得到相关的 IP地址。
通过类 Applet的 getCodeBase()方法获得提供它的主机的 URL实例
利用类 URL的 getHost()方法得到主机名
利用类 InetAddress的 getByName()得到该主机的 IP地址
通过 IP地址,就可以进行网络通信( TCP,UDP)
URL url = getCodeBase();
String host = url.getHost();
Try{
InetAddress address = InetAddress.getByName(host);
}catch(Exception e){}
Try{
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf,length,address,port);
socket.send(packet);
}catch(Exception e){}
12.4 基于 URL的网络编程 ——URL连接通过 URL类提供的方法 openConnection(),就可以获得一个 URL连接( URLConnection)对象。
public URLConnection openConnection()
通过 URL的方法 openStream(),只能从网络上读取资源中的数据。通过 URLConnection类,可以在应用程序和
URL资源之间进行交互,既可以从 URL中读取数据,也可以向 URL中发送数据。 URLConnection类表示了应用程序和 URL资源之间的通信连接。
try{
URL url = new URL(“http://gis.pku.edu.cn”);
URLConnection uc = url.openConnection();
}catch(MalformedURLException e1){

}catch(IOException e2){

}
public class URLConnectionReader
{
public static void main (String args[])
{
try{
URL gis = new URL("http://gis.pku.edu.cn/test.htm");
URLConnection uc = gis.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader( uc.getInputStream() ) );
String line;
while( (line = in.readLine()) != null )
{
System.out.println(line);
}
in.close();
}catch(Exception e){
System.out.println(e);
}
}
}
通过 getInputStream()
方法,应用程序就可以读取资源中的数据。
事实上,类 URL的方法 openStream()就是通过 URLConnection类来实现的,它等价于:
openConnection().getInputStream();
URLConnection中最常用的两个方法是:
public InputStreamgetInputStream()
public OutputStreamgetOutputStream()
12.4 基于 URL的网络编程 ——URL连接通过 URLConnection对象获取的 输入流 和 输出流 (不是所有的资源都可以获得有效的输出流),可以与现有的 CGI程序 进行交互。 URL和 URLConnection的区别在于前者代表一个资源的位置,后者代表一种连接。
客户端
java程序
OutputStream
InputStream
CGI程序
STDIN
STDOUT
服务器connection getchar()putchar()
URL url = new URL("http://gis.pku.edu.cn/~lyw/cgi-bin/test.cgi");
URLConnection uc = url.openConnection();
uc.setDoOutput(true);
PrintStream out = new PrintStream(uc.getOutputStream());
BufferedReader in = new BufferedReader(
new InputStreamReader( uc.getInputStream() ) );
12.4 基于 URL的网络编程 ——URL连接
12.5 基于 Socket的网络编程在 Java中,基于 TCP协议实现网络通信的类有两个:在客户端的 Socket类和在服务器端的 ServerSocket类。
在服务器端通过指定一个用来等待的连接的端口号创建一个 ServerSocket实例。
在客户端通过规定一个主机和端口号创建一个
Socket实例,连到服务器上。
ServerSocket类的 accept方法使服务器处于阻塞状态,
等待用户请求。
构造方法:
public Socket(String host,int port) //远程服务器 IP及响应端口
public Socket(InetAddress address,int port)
public Socket(String host,int port,InetAddress localAddr,int localPort)
public Socket(InetAddress address,int port,InetAddress localAddr,
int localPort)
//在指定的机器上的指定端口上运行在 JDK1.1以前,Socket类可同时用于 TCP/UDP通信:
public Socket(String host,int port,boolean stream)
public Socket(InetAddress host,int port,boolean stream)
这些方法都将抛出例外 IOException,程序中需要捕获处理。
12.5 基于 Socket的网络编程 ——类 Socket
Socket的输入 /输出流管理
public InputStream getInputStream()
public void shutdownInput()
public OutputStream getOutputStream()
public void shutdownOutput()
这些方法都将抛出例外 IOException,程序中需要捕获处理。
关闭 Socket
public void close() throws IOException
设置 /获取 Socket数据
public InetAddress getInetAddress(),public int getPort(),…
public void setSoTimeout(int timeout),…
这些方法都将抛出例外 SocketException,程序中需要捕获处理。
12.5 基于 Socket的网络编程 ——类 Socket
构造方法:
public ServerSocket(int port)
public ServerSocket(int port,int backlog) //支持指定数目的连接
public ServerSocket(int port,int backlog,InetAddress bindAddr)
//在指定的机器上运行这些方法都将抛出例外 IOException,程序中需要捕获处理。
主要方法
public Socket accept():等待客户端的连接
public void close():关闭 Socket
设置 /获取 Socket数据
public InetAddress getInetAddress(),public int getLocalPort(),…
public void setSoTimeout(int timeout),…
这些方法都将抛出例外 SocketException,程序中需要捕获处理。
12.5 基于 Socket的网络编程 ——类 ServerSocket
12.5 基于 Socket的网络编程 —Socket通信无论一个 Socket通信程序的功能多么齐全、程序多么复杂,其基本结构都是一样的,都包括以下四个基本步骤:
1、在客户方和服务器方创建 Socket/ServerSocket实例。
2、打开连接到 Socket的输入 /输出流。
3、利用输入 /输出流,按照一定的协议对 Socket进行读 /
写操作。
4、关闭输入 /输出流和 Socket。
通常,程序员的主要工作是针对所要完成的功能在第 3
步进行编程,第 1,2,4步对所有的通信程序来说几乎都是一样的。
Server端程序
ServerSocket(port #)
Socket socket =
ServerSocket.accept()
接收连接
OutputStream
InputStream
Close Socket
Client端程序
Socket(host,port #)
与服务器建立连接
OutputStream
InputStream
Close Socket
socket
12.5 基于 Socket的网络编程 —Socket通信
1、建立 Socket
在客户端:
try{
Socket client = new Socket(host,4444);
}catch(IOException e){}
在服务器端:
try{
ServerSocket server = new ServerSocket(4444);
}catch(IOException e){}
Socket socket = null;
try{
socket = server.accept(); //等待客户端连接
}catch(IOException e){}
12.5 基于 Socket的网络编程 —Socket通信
BufferedReader = new BufferedReader(
new InputStreamReader( socket.getInputStream() ) );
BufferedWriter = new BufferedWriter(
new InputStreamWriter( socket.getOutputStream() ) );
2、在客户端和服务器端同时打开输入 /输出流类 Socket提供了方法 getInputStream()和 getOutputStream()来得到
Socket对应的输入 /输出流以进行数据读写(传输)操作,它们分别返回 InputStream对象和 OutputStream对象。
为了便于读写数据,应在返回的输入 /输出流对象上建立过滤流,如
DataInputStram/DataOutputStram,BufferedInputStream/ BufferedOutputStream、
PrintStream; InputStreamReader/ OutputStreamWriter,BufferedReader/
BufferedWriter,PrintWriter等。
12.5 基于 Socket的网络编程 —Socket通信
3、关闭输入 /输出流和 Socket
在客户端和服务器端分别关闭输入 /输出流和 Socket:先关闭所有相关的输入 /输出流,再关闭 Socket。
12.5 基于 Socket的网络编程 —Socket通信创建服务器 (端口号 )
定义数据成员服务器等待网络连接建立 socket流发送谈话信息接收用户谈话信息创建 Socket实例定义数据成员建立 socket流发送谈话信息接收服务器谈话信息关闭流
accept()
4444
结束谈话 (Bye.) 结束谈话 (Bye.)
关闭流服务器端客户端
12.5 基于 Socket的网络编程 ——
简单的 Client/Server
在本地机器上测试网络程序用 回绕地址
Socket socket = new Socket(“127.0.0.1”,4444);
建立 socket连接后,还应该建立输入输出数据流。
要控制好输入 /输出流和 Socket关闭的时间。
如果网络的一端已经关闭,另一端读到 null。
在运行时,服务器端程序一般应先行启动。
Server(1111)
client(2222)Server(2222)
client(1111)
Server
解决方案一:
在一台计算机上一次启动多个服务器程序,只要端口号不同。
myserver1 <-------->myclient1
myserver2<-------->myclient2
12.5 基于 Socket的网络编程 ——
支持多 Client
解决方案二:
将服务器写成多线程的,不同的处理线程为不同的客户服务。主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息。
//主线程
while (true)
{
accept a connection ;
create a thread to deal with the client ;
}end while
Serverclient1
client2
serverthread2
serverthread1
……
12.5 基于 Socket的网络编程 ——
支持多 Client
serverSocket = new ServerSocket(4444);
while (listening)
{
Socket socket;
socket = serverSocket.accept(); //程序将在此等候客户端的连接
clientNumber++; //记录客户数目
new MultiTalkServerThread(socket,clientNumber).start(); //创建一个新线程处理此客户请求
}
serverSocket.close();
class MultiTalkServerThread extends Thread{
public MultiTalkServerThread(Socket socket,int clientNumber){
this.socket = socket;this.clientNumber = clientNumber;
}public void run()
{ …
}}
12.5 基于 Socket的网络编程 ——
支持多 Client
客户 1
客户 2
服务器线程 1( )
线程 2( )
12.5 基于 Socket的网络编程 ——
支持多 Client
12.5 基于 Socket的网络编程 ——
Client之间通过 Server通信可以在服务器端将与各客户进行通信的 Socket和线程管理起来,从而各客户之间可以在服务器端的协助下进行通信。
服务器
(4444)
accept
socket
客户
2
IP1 client1
线程 1
客户
1
IP2 client2
线程 2
数据报( Datagram)是一种尽力而为的传送数据的方式,它只是把数据的目的地记录在数据包中,然后就直接放在网络上,系统不保证数据是否能安全送到,或者什么时候可以送到,也就是说它并不保证传送质量。
数据报( Datagram)是网络层数据单元在介质上传输信息的一种逻辑分组格式。它是一种在网络中传播的、独立的、自身包含地址信息的消息。
它能否到达目的地、到达的时间、到达时内容是否会变化不能准确地知道。它的通信双方是不需要建立连接的,对于一些不需要很高质量的应用程序来说,数据报通信是一个非常好的选择。还有就是对实时性要求很高的情况,如在实时音频和视频应用中,数据包的丢失和位置错乱是静态的,是可以被人们所忍受的,但是如果在数据包位置错乱或丢失时要求数据包重传,就是用户所不能忍受的。这时就可以利用 UDP协议传输数据包。在 Java的 java.net包中有两个类 DatagramSocket和
DatagramPacket,为应用程序中采用数据报通信方式进行网络通信。
12.6数据报通信的应用
UDP协议是无连接的协议,它以 数据报 作为数据传输的载体。数据报是一个在网络上发送的独立信息,它的到达、到达时间以及内容本身等都不能得到保证。数据报的大小是受限制的,每个数据报的大小限定在 64KB以内。
UDP协议无需在发送方和接收方建立连接,但也可以先建立连接。数据报在网上可以以任何可能的路径传往目的地。
在 Java中,基于 UDP协议实现网络通信的类有三个:
用于表达通信数据的数据报类 DatagramPacket
用于进行端到端通信的类 DatagramSocket
用于广播通信的类 MulticastSocket。
12.6数据报通信的应用
datagram
server client
构造方法
public DatagramPacket(byte[] buf,int length)
public DatagramPacket(byte[] buf,int offset,int length)
//这两个方法用于描述接收数据报
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
public DatagramPacket(byte[] buf,int offset,int length,InetAddress address,int port)
//这两个方法用于发送数据报获取数据 ——获取 接收数据报 中的信息
public InetAddress getAddress()
public byte[] getData()
public int getLength()
public int getOffset()
public int getPort()
设置数据 ——设置 发送数据报 中的信息
setAddress(InetAddress iaddr),setPort(int iport),setData(byte[] buf)、
setData(byte[] buf,int offset,int length),setLength(int length)
12.6数据报通信的应用 ——
数据报:类 DatagramPacket
构造方法
public DatagramSocket()
public DatagramSocket(int port) //在指定的端口通信
public DatagramSocket(int port,InetAddress laddr) //在指定的地点运行这三个方法都将抛出例外 SocketException,程序中需要捕获处理。
最主要的方法 ——发送与接收数据报
public void receive(DatagramPacket p)
public void send(DatagramPacket p)
这两个方法都将抛出例外 IOException,程序中需要捕获处理。
其他方法
public void connect(InetAddress address,int port) //与指定的机器通信,有连接
public void disconnect() //关闭与指定机器的连接
public void close() //关闭 Socket
12.6数据报通信的应用 ——
点到点通信:类 DatagramSocket
建立数据报 socket
建立一个接收数据报等待请求报文建立数据报 socket
建立一个请求数据报 (发送 )
发出请求获得对方地址 (通过接收数据报 )
构成发送数据报发送出去创建接收数据报等待接收接收端(客户端)发送端(服务器端)
12.6数据报通信的应用 ——点到点通信发送端(服务器端) 发出数据报的标准步骤:
1,定义数据成员
DatagramSocket socket;
DatagramPacket packet;
InetAddress address;(用来存放接收方的地址 )
int port; (用来存放接收方的端口号 )
2,创建数据报 Socket对象
try{
socket = new DatagramSocket(4445);
}catch(java.net.SocketException e) {}
socket 绑定到一个本地的可用端口,等待接收客户端的请求。
3.分配并填写数据缓冲区 (一个字节类型的数组 )
byte[] buf = new byte[256];
存放从客户端接收的请求信息。
4.创建一个 接收数据报 DatagramPacket
packet = new DatagramPacket(buf,256);
用来从 socket接收数据,它只需要两个参数。
5,服务器阻塞(等待接收数据)
socket.receive(packet);
在客户的请求数据报到来之前一直等待。
12.6数据报通信的应用 ——点到点通信
6,从到来的 接收数据报 中得到客户端的地址和端口号
InetAddress address = packet.getAddress();
int port = packet.getPort();
7,准备需要发送的数据:将数据送入缓冲区 buf
或来自文件、或键盘输入
8,建立 发送数据报,用来从 socket向客户端发送信息
packet = new DatagramPacket(buf,buf.length,address,port);
9,发送数据包
socket.send(packet);
10.关闭 socket
socket.close();
12.6数据报通信的应用 ——点到点通信接收端(客户端) 接收数据报的标准步骤:
1,定义数据成员
int port;
InetAddress address;
DatagramSocket socket;
DatagramPacket packet;
byte[] sendBuf = new byte[256];
2,建立 socket
socket = new DatagramSocket();
无须指定端口号,它会自动获得一个可用的端口号。
12.6数据报通信的应用 ——点到点通信
3,向服务器端发出请求数据报( 发送数据报 )
address = InetAddress.getByName(args[0]);
port = parseInt(args[1]);
//获得服务器端的 IP和端口号
packet = new DatagramPacket(sendBuf,256,address,port);
socket.send(packet);
这个数据报本身会带有客户端的信息
4,客户端等待服务器端的应答(通过 接收数据报 接收数据)
packet=new DatagramPacket(sendBuf,256);
socket.receive(packet);
如果没有到就一直等待,因此实用程序要设置等待时间限度
5,处理接收到的数据
String received=new String(packet.getData(),0);
System.out.println(received);
12.6数据报通信的应用 ——点到点通信
6、数据报通信
——广播通信
DatagramSocket只允许数据报发往一个目的地址。
java.net类包中提供了类 MulticastSocket,允许将数据报以广播的方式发送到某个端口的所有客户。
类 MulticastSocket是在客户端(接收端)使用,
监听服务器端广播来的数据;而服务器端仍然使用
DatagramSocket来发送数据,只是发送的数据报的目的地址有所变化。
类 MulticastSocket:从 DatagramSocket继承而来构造方法
public MulticastSocket()
public MulticastSocket(int port),在指定的端口通信这两个方法都将抛出例外 IOException,程序中需要捕获处理。
主要方法
public void joinGroup(InetAddress mcastaddr),加入一个广播组
public void leaveGroup(InetAddress mcastaddr),离开一个广播组
public void setTimeToLive(int ttl),指定数据报离开时间
public void send(DatagramPacket p,byte ttl),在指定的时间内将数据报发送出去这四个方法都将抛出例外 IOException,程序中需要捕获处理。
继承 DatagramSocket的方法
public void receive(DatagramPacket p):接收数据
public void send(DatagramPacket p):发送数据
public void connect(InetAddress address,int port):与指定的机器通信
public void disconnect():关闭指定的连接
public void close():关闭 Socket
12.6数据报通信的应用 ——广播通信
MulticastSocket socket = new MulticastSocket(4446);
InetAddress group = InetAddress.getByName("230.0.0.1");
socket.joinGroup(group);
… //receive datagram
socket.leaveGroup(group);
socket.close();
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet =
new DatagramPacket(buf,buf.length,group,4446);
socket.send(packet);
客户端服务器端
12.6数据报通信的应用 ——广播通信广播组的 IP地址是一类特殊的 IP地址,它们没有分配给网上的硬件资源使用,而是专门保留下来作为广播通信使用的(就像 127.0.0.1是专门用来描述本机 IP一样)。这一类地址的范围是从 224.0.0.0到
239.255.255.255,其中地址 224.0.0.0又被保留不能被一般应用程序所使用。
当前,广播通信只能在应用程序中使用,不能在
Applet中使用。
12.6数据报通信的应用 ——广播通信