Java网络编程从入门到精通(15):为什么要使用SocketAddress来管理网络地址

在使用Socket来连接服务器时最简单的方式就是直接使用IP和端口,但Socket类中的connect方法并未提供这种方式,而是使用SocketAddress类来向connect方法传递服务器的IP和端口。虽然这种方式从表面上看要麻烦一些,但它会给我们带来另外一个好处,那就是网络地址的重用。
所谓网络地址的重用表现在两个方面:

1. 通过建立一个SocketAddress对象,可以在多次连接同一个服务器时使用这个SocketAddress对象。
2. 在Socket类中提供了两个方法:getRemoteSocketAddress和getLocalSocketAddress,通过这两个方法可以得到服务器和本机的网络地址。而且所得到的网络地址在相应的Socket对象关闭后任然可以使用。下面是这两个方法的声明:

public SocketAddress getRemoteSocketAddress() public SocketAddress getLocalSocketAddress()

不管在使用Socket类连接服务器时是直接使用IP和端口,还是使用SocketAddress,这两个方法都返回SocketAddress形式的网络地址。当Socket对象未连接时这两个方法返回null,但要注意的是只有在Socket对象未连接时这两个方法才返回null,而当已经连接成功的Socket对象关闭后仍可使用这两个方法得到相应的网络地址。
    虽然上面曾多次提到SocketAddress,但SocketAddress只是个抽象类,它除了有一个默认的构造方法外,其它的方法都是abstract的,因此,我们必须使用SocketAddress的子类来建立SocketAddress对象。在JDK1.4中J只为我们提供了IP网络地址的实现类:java.net.InetSocketAddress。这个类是从SocketAddress继承的,我们可以通过如下的方法来建立SocketAddress对象。

SocketAddress socketAddress = new InetSocketAddress(host, ip);

下面的代码演示了如何通过SocketAddress来共享网络地址:

package mynet;
import java.net.*;
public class MySocketAddress {

public static void main(String[] args)

{

try

{

Socket socket1 = new Socket("www.ptpress.com.cn", 80);

SocketAddress socketAddress = socket1.getRemoteSocketAddress();

socket1.close();

Socket socket2 = new Socket();

// socket2.bind(new InetSocketAddress("192.168.18.252", 0));

socket2.connect(socketAddress);

socket2.close();

InetSocketAddress inetSocketAddress1 = (InetSocketAddress) socketAddress;

System.out.println("服务器域名:" + inetSocketAddress1.getAddress().getHostName());

System.out.println("服务器IP:"  + inetSocketAddress1.getAddress().getHostAddress());

System.out.println("服务器端口:" + inetSocketAddress1.getPort());

InetSocketAddress inetSocketAddress2 = (InetSocketAddress) socket2 .getLocalSocketAddress();

System.out.println("本地IP:" + inetSocketAddress2.getAddress().getLocalHost() .getHostAddress());

System.out.println("本地端口:" + inetSocketAddress2.getPort());

}

catch (Exception e)

{

System.out.println(e.getMessage());

}

}

}

输出结果:

服务器域名:www.ptpress.com.cn
服务器IP:219.238.168.74
服务器端口:80
本地IP:192.168.18.253
本地端口:4250

如果多次运行例程4-10后,本地端口的值可能在每次都不一样。这是因为在socket2在连接时并未使用bind来绑定本地的端口,而这个本地端口是由系统在1024至65,535中随机选取的,因此,在每次运行程序时这个本地端口不一定相同。

时间: 2024-09-30 07:32:31

Java网络编程从入门到精通(15):为什么要使用SocketAddress来管理网络地址的相关文章

Java网络编程从入门到精通(4):DNS缓存

在通过DNS查找域名的过程中,可能会经过多台中间DNS服务器才能找到指定的域名,因此,在DNS服务器上查找域名是非常昂贵的操作.在Java中为了缓解这个问题,提供了DNS缓存.当InetAddress类第一次使用某个域名(如www.csdn.net)创建InetAddress对象后,JVM就会将这个域名和它从DNS上获得的信息(如IP地址)都保存在DNS缓存中.当下一次InetAddress类再使用这个域名时,就直接从DNS缓存里获得所需的信息,而无需再访问DNS服务器. DNS缓存在默认时将永

Java网络编程从入门到精通 (9):使用isXxx方法判断地址类型

IP地址分为普通地址和特殊地址.在前面的文章中所使用的大多数都是普通的IP地址,在本文中将介绍如何利用InetAddress类提供的十个方法来确定一个IP地址是否是一个特殊的IP地址. 一.isAnyLocalAddress方法 当IP地址是通配符地址时返回true,否则返回false.这个通配符地址对于拥有多个网络接口(如两块网卡)的计算机非常拥有.使用通配符地址可以允许在服务器主机接受来自任何网络接口的客户端连接.IPv4的通配符地址是0.0.0.0.IPv6的通配符地址是0:0:0:0:0

Java网络编程从入门到精通(18):Socket类的getter和setter方法(2)

二.用于获得和设置Socket选项的getter和setter方法 Socket选择可以指定Socket类发送和接受数据的方式.在JDK1.4中共有8个Socket选择可以设置.这8个选项都定义在java.net.SocketOptions接口中.定义如下: public final static int TCP_NODELAY = 0x0001;    public final static int SO_REUSEADDR = 0x04;    public final static int

Java网络编程从入门到精通(16):客户端套接字(Socket)的超时

客户端套接字的超时(timeout)就是指在客户端通过Socket和服务器进行通讯的过程中,由于网络延迟,网络阻塞等原因,造成服务器并未及时响应客户端的一种现象.在一段时间后,客户端由于未收到服务端的响应而抛出一个超时错误; 其中客户端所等待的时间就是超时时间. 由于生产超时错误的一端都是被动端:也就是说,这一端是在接收数据,而不是发送数据.对于客户端Socket来说,只有两个地方是在接收数据:一个是在连接服务器时;另一个是在连接服务器成功后,接收服务器发过来的数据时.因此,客户端超时也分为两种

Java网络编程从入门到精通(14):多种多样的建立网络连接的方式

在上一篇文章中我们讨论了Socket类的基本用法,并给出的例子中使用Socket类连接服务器时使用了一种最简单的连接方式,也就是通过IP和端口号来连接服务器.而为了使连接服务器的方式更灵活,Socket类不仅可以通过自身的构造方法连接服务器,而且也可以通过connect方法来连接数据库. 一.通过构造方法连接服务器 我们可以通过6个重载构造函数以不同的方式来连接服务器.这6个重载的构造函数可以分为两类: 1. 自动选择IP     这种方式是最常用的.所谓自动选择IP,是指当本机有多块网卡或者在

Java网络编程从入门到精通(13):使用Socket类接收和发送数据

网络应用分为客户端和服务端两部分,而Socket类是负责处理客户端通信的Java类.通过这个类可以连接到指定IP或域名的服务器上,并且可以和服务器互相发送和接受数据.在本文及后面的数篇文章中将详细讨论Socket类的使用,内容包括Socket类基础.各式各样的连接方式.get和set方法.连接过程中的超时以及关闭网络连接等. 在本文中,我们将讨论使用Socket类的基本步骤和方法.一般网络客户端程序在连接服务程序时要进行以下三步操作. 1.         连接服务器 2.         发送

Java网络编程从入门到精通(8):用getAddress方法获得IP地址

getAddress方法和getHostAddress类似,它们的唯一区别是getHostAddress方法返回的是字符串形式的IP地址,而getAddress方法返回的是byte数组形式的IP地址.getAddress方法的定义如下: public byte[] getAddress() 这个方法返回的byte数组是有符号的.在Java中byte类型的取值范围是-128?127.如果返回的IP地址的某个字节是大于127的整数,在byte数组中就是负数.由于Java中没有无符号byte类型,因此

Java网络编程从入门到精通(7):用getHostAddress方法获得IP地址

 这个方法用来得到主机的IP地址,这个IP地址可能是IPv4的地址,也可能是IPv6的地址.getHostAddress方法的定义如下: public String getHostAddress() 无论InetAddress对象是使用哪种方式创建的,getHostAddress方法都不会访问DNS服务器.如果想访问使用IPv6地址的远程主机,需要在操作系统上安装IPv6协议.下面是Windows 2003上安装IPv6协议的步骤: 第一步:打开“本地连接”属性对话框.如图1所示. 图1 “本地

Java网络编程从入门到精通(5):使用InetAddress类的getHostName方法获得域名

该方法可以得到远程主机的域名,也可以得到本机名.getHostName方法的定义如下: public String getHostName() 下面是三种创建InetAddress对象的方式,在这三种方式中,getHostName返回的值是不同的. 1.使用getLocalHost方法创建InetAddress对象 如果InetAddress对象是用getLocalHost方法创建的,getHostName返回的是本机名.如下面的代码所示: InetAddress address = InetA