很多學習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);
//忽略接收代碼
}
}
閱讀更多 吳濤分享 的文章