引言
Java支持 基于流的通信 (使用TCP) 和 基于包的通信 (使用UDP) ,大多数Java程序采用前者,无损可靠。
套接字:两台主机之间逻辑连接的端点,可以用来发送和接收数据。
Java对套接字通信的处理非常类似于对输入输出操作的处理,所以就想对文件读写差不多。
网络程序设计通常涉及一个 Server 和最少一个 Client ,一旦建立连接,二者就可以通过套接字进行通信。
必须先有服务器,客户端的请求才会被处理。
Java提供 ServerSocket 类来创建服务器套接字,Socket 类来创建客户端。
服务器套接字
要创建服务器,需要创建一个 服务器套接字 ,并把它附加到一个端口上,服务器从这个端口监听连接,端口 标识 套接字上的TCP服务,端口号的范围是0~65536,但是0~1024是保留端口号,不可用,比如电子邮件服务器运行在端口25上,Web服务器通常运行在端口80上,如果在已经使用的端口上创建服务器套接字,就会导致java.net.BindException,下面举个例子:
ServerSocket serverSocket = new ServerSocket(port); // 创建服务器套接字
Socket socket = serverSocket.accept(); // 监听连接,一直等待直到有客户端连接到服务器套接字
客户端套接字
Socket socket = new Socket(serverName, port); // serverName 是主机名或者IP地址
上面语句打开一个套接字,使得客户端和服务器能够通信,比如:
Socket socket = new Socket("130.254.204.33", 8000);
Socket socket = new Socket("liang.armstrong.edu", 8000);
如果找不到主机,则抛出 java.net.UnknownHostException
通过套接字进行数据传输
服务器接受连接之后,Server 和 Client 之间的通信就像 I/O 流一样进行操作。
为了获得输入流和输出流,对套接字对象使用 getInputStream() 方法和 getOutputStream() 方法,如下:
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
InputStream 流和 OutputStream 流分别用来读取和写入字节。
为了读写 int, double, String 之类的数据,可以用 DataInputStream, DataOutputStream, BufferedReader, PrintWriter 来包装 InputStream 和 OutputStream,例如:
DataInputStream input = new DataInputStream(socket.getInputStream));
DataOutputStream output = new DataOutputStream(socket.getOutputStream));
客户端/服务器示例
下面的程序给出了一个客户端程序和一个服务器程序,用来计算圆的面积,客户端输入,服务器计算并返回,客户端接收并在控制台上显示结果
InetAddress 类
Server 可以用 InetAddress 类来获得 Client 的 IP地址 和 HostName 等信息
该类对 IP地址建模
在服务器中使用下面的语句可以得到与客户端相连的套接字上的一个 InetAddress 实例:
InetAddress inetAddress = socket.getInetAddress();
inetAddress.getHostName(); // 返回客户端的主机名
inetAddress.getHostAddress(); // 返回客户端的IP地址
下面举个小栗子,该程序通过命令行参数返回主机名和IP地址,需要命令行参数,可以在命令行中输入:
java IdentifyHostNameIP www.baidu.com 130.254.204.34
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IdentifyHostNameIP {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
try {
InetAddress address = InetAddress.getByName(args[i]);
System.out.print("Host name: " + address.getHostName() + "\t");
System.out.println("IP address: " + address.getHostAddress());
} catch (UnknownHostException ex) {
System.err.println("Unknown host or IP address " + args[i]);
}
}
}
}