很多学习JAVA的人对网络编程都不怎么重视,实际上在工作中网络编程确实很重要。例如断点续传、RPC框架底层实现等技术都需要开发者对网络编程有深入的理解和掌握。
1. 网络地址
网络地址 = IP地址(域名) + 端口号。在JAVA中,IP地址是一个 java.net.InetAddress 对象,IP地址有V4和V6,对应Inet4Address和Inet6Address(这两个属于导出类,你大可放心的把这俩忘掉)。JAVA把计算机相互通信的一端抽象成Socket,Socket关联着计算机的IP地址和端口。
JAVA眼中的网络地址:
InetAddress:代表IP地址
InetSocketAddress:代表IP Socket地址
NetworkInterface:代表本地计算机网络接口,或许是一组网卡的接口抽象。
JAVA眼中的Socket:
Socket
ServerSocket
DatagramSocket
MulticastSocket(一个主机有多个IP地址)
2. TCP协议
2.1 TCP连接以及断开过程
TCP是全双工,可同时双向传输。
三次握手
客户端SYN
服务响应SYN/ACK
客户端ACK
四次挥手
2.2 JAVA中Socket的编程范例
Server端代码最佳实践
class ConcurrentTcpServer implements Runnable{
public static final int BUFFER_SIZE = 128 * 1024;
public static final int TIMEOUT = 30 * 1000; // 30s
private ServerSocket serverSocekt;
public ConcurrentTcpServer(int port){
//1.不要设置本地地址,直接使用port
serverSocekt = new ServerSocket(port);
//2.在没有客户端连接之前设置服务端接收buffer大小。
serverSocekt.setReceiveBufferSize(BUFFER_SIZE);
}
@Override
public void run(){
while(true){
Socket socket = serverSocket.accept();
//4.设置发送数据buffer大小
socket.setSendBufferSize(BUFFER_SIZE);
//5.设置客户端连接超时时间,不要无限等待客户端。
socket.setSoTimeout(TIMEOUT);
new Thread(new ConnectionHandler(socket)).start();
}
}
}
Client端代码最佳实践
Public class TCPClient implements Runnable{
public static final int BUFFER_SIZE = 128 * 1024;
public static final int TIMEOUT = 30 * 1000;
private Socket socket;
public TCPClient(String host,int port){
this.socket = new Socket();
//1.设置接收大小
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.connection(new InetSocketAddress(host,port));
//2.超时时间
socket.setSendBufferSize(BUFFER_SIZE);
socket.setSoTimeout(TIMEOUT);
}
public void run(){
OutputStream out = new BufferedOutputStream(socket.getOutputStream(),BUFFER_SIZE);
//忽略发送代码
out.flush();
InputStream in = new BufferedInputStream(socket.getInputStream(),BUFFER_SIZE);
//忽略接收代码
}
}