网络编程基本概念:
1 IP(Internet Protocol) 是加入互联网每一个设备的独一编号。IPv4系统中IP地址为四个0-255之间数字,如192.168.1.245。我们一般将IP地址对应域名(domain name)便于记忆,一种专门的服务器DNS(domain name server)可以将域名翻译为IP地址
2 和IP同时用于传输数据的协议还有TCP(Transmission Control Protocol)或UDP(User Datagram Protocol)。TCP实现基于数据流传输(steam-based communication),并且保证了传输数据顺序的一致性和补发丢失数据的能力。UDP实现两个电脑应用程序间通信,使用基于包传输(packet-based communication)。但UDP不具有TCP检测传输损失并补发的能力
客户端/服务器通信:
Java提供ServerSocket和Socket类用于通信。两个程序使用I/O流进行联网通信
Socket是两个主机间通信终端,可以用于发送和接收数据
创建服务器:
要创建服务器,需要创建一个ServerSocket类并连接一个port,即服务器应该从哪里接收连接。TCP通信port值在0-65536,其中0-1024保留给高级服务
ServerSocket serverSocket = new ServerSocket(port)
如果在一个已经被占用的port上创建ServerSocket会报错java.net.BindException
当服务器创建好后,等待连接:
Socket socket = serverSocket.accept()
创建客户端:
当服务器开始等待连接后,客户端用以下指令请求服务
Socket socket = new Socket(serverName, port)
参数serverName为服务器的IP或域名,如果为本地服务器可以输入"localhost"或127.0.0.1
如果找不到host会报错java.net.UnknownHostException
客户端和服务器传输数据示例
服务器:
package networking;
import java.io.*;
import java.net.*;
import java.util.Date;
public class Server {
public static void main(String[] args) {
Thread server = new Thread(new Runnable() {
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8000);
Socket socket = serverSocket.accept();
DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
while(true) {
double radius = inputFromClient.readDouble();
double area = radius * radius * Math.PI;
outputToClient.writeDouble(area);
System.out.println("Radius received: " + radius);
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
});
server.start();
1
ServerSocket serverSocket = new ServerSocket(8000);
Socket socket = serverSocket.accept();
创建1服务器socket并等待客户端请求
2
DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
创建InputStream和OutputStream读写字节。使用binary I/O效率要高于text I/O。
inputFromClient使用readDouble读取客户端发送的double数据。outputToClient使用writeDouble向客户端写入double数据
客户端:
package networking;
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread client = new Thread(new Runnable() {
public void run() {
try {
Socket socket = new Socket("localhost", 8000);
DataOutputStream toServer = new DataOutputStream(socket.getOutputStream());
DataInputStream fromServer = new DataInputStream(socket.getInputStream());
while(true) {
try {
double radius = 5;
toServer.writeDouble(radius);
toServer.flush();
double area = fromServer.readDouble();
System.out.println("Area: " + area);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException ex) {
System.out.println(ex.toString());
}
}
});
client.start();
}
}
1
Socket socket = new Socket("localhost", 8000);
创建客户端socket,连接本机IP localhost的port 8000
后面数据流读写的程序和服务器基本一致
使用InetAddress查找socket的IP地址:
InetAddress构造方法:
1 使用socket对象构造:
InetAddress intAddress = socket.getInetAddress();
2 使用getByName创造,参数输入服务器域名:
InetAddress address = InetAddress.getByName(“www.whitehouse.gov”);
InetAddress方法
1 getHostAddress(): 得到目标socket的IP地址
2 getHostName(): 得到目标socket名称
package networking;
import java.net.*;
public class IdentifyHostNameIP {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
InetAddress address = InetAddress.getByName("www.whitehouse.gov");
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
}
}