概述
網絡編程從大的方面說就是對信息的發送到接收,中間傳輸爲物理線路的作用。
網絡編程最主要的工作就是在發送端把信息通過規定好的協議進行組裝包,在接收端按照規定好的協議把包進行解析,從而提取出對應的信息,達到通信的目的。
網絡編程最主要的目的就是進行數據的交換、通信。
網絡通信的要素
進行網絡通信的時候,我們需要知道通信雙方的主機的地址,即需要知道IP以及端口號。
同時,在進行網絡通信的時候,通信雙方必須遵循相同的通信協議纔可以進行通信。
IP、端口
IP
IP 是唯一定位了網絡上的一臺計算機,在Java中有關IP的類是InetAddress,該類表示 Internet Protocol version 4 (IPv4) 地址。
public final class Inet4Address
extends InetAddress
IP地址爲127.0.0.1,表示的是本機地址即localhost
public class TestIP {
public static void main(String[] args) {
try {
// 查詢本機IP地址
InetAddress address = InetAddress.getByName("127.0.0.1");
InetAddress address1 = InetAddress.getByName("localhost");
InetAddress address2 = InetAddress.getLocalHost();
System.out.println(address);
System.out.println(address1);
System.out.println(address2);
System.out.println(address.getAddress());
System.out.println(address.getCanonicalHostName());
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
// 查詢網站的IP地址
InetAddress address3 = InetAddress.getByName("www.csdn.net");
System.out.println(address3);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口
端口是用來表示計算機上的一個程序的進程。
- 不同的進程有不同的端口號,是用來區分軟件的。
- 端口號規定的範圍是0~65535。
- 不同的協議中的端口號可以相同,但是同一個協議下,端口號不能相同,否則會衝突。
端口分類
- 公有端口:0~1023
- 程序註冊端口:1024~49151, 分配用戶或者程序
- 動態、私有:49152~ 65535
端口號 | 協議 |
---|---|
21 | FTP(文件傳輸服務) |
22 | SSH( 遠程連接服務) |
23 | Telent(終端仿真服務) |
25 | SMTP(簡單郵件傳輸服務) |
53 | DNS(域名解析服務) |
80 | HTTP(超文本傳輸服務) |
443 | HTTPS(加密的超文本傳輸服務) |
1521 | Oracle數據庫 |
3306 | MYSQL數據庫 |
5432 | postgresql數據庫 |
6379 | Redis數據庫 |
8080 | TCP服務端默認端口 |
8888 | Nginx服務器 |
9200 | Elasticsearch服務器 |
27017 | mongoDB數據庫 |
22122 | fastdfs服務器 |
可以使用如下命令查看端口
netstat -ano #查看所有的端口
netstat -ano|findstr "5900" # 查看指定的端口
tasklist|findstr "8696" #查看指定端口的進程
InetSocketAddress類
public class InetSocketAddress
extends SocketAddress
InetSocketAddress類實現 IP 套接字地址(IP 地址 + 端口號)。它還可以是一個對(主機名 + 端口號),在此情況下,將嘗試解析主機名。
public class TestPort {
public static void main(String[] args) {
try {
InetSocketAddress address = new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress address1 = new InetSocketAddress("localhost",8080);
System.out.println(address);
System.out.println(address1);
System.out.println(address.getAddress());
System.out.println(address.getHostName());
System.out.println(address.getHostString());
System.out.println(address.getPort());
} catch (Exception e) {
e.printStackTrace();
}
}
}
通信協議
有關通信協議,我們最常聽到的就是TCP/IP協議,這是一個協議簇。
這裏我們主要使用的是TCP和UDP協議。
TCP是需要建立連接的,是穩定的。
通信雙方使用TCP協議進行通信的時候需要:
- 先建立連接
- 再進行數據傳輸
- 最後釋放連接
UDP是不需要建立連接的,是不穩定的。
TCP
public class Socket
extends Object
Socket類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩臺機器間通信的端點。
public class ServerSocket
extends Object
ServerSocket類實現服務器套接字。服務器套接字等待請求通過網絡傳入。它基於該請求執行某些操作,然後可能向請求者返回結果。
消息傳輸
客戶端:
public class TestClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream os =null;
try {
// 1. 需要知道服務器的地址和端口號
InetAddress address = InetAddress.getByName("127.0.0.1");
int port=8080;
// 2. 創建一個socket連接
socket = new Socket(address,port);
// 3. 發送消息 使用IO流
os = socket.getOutputStream();
os.write("歡迎學習Java".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
服務端:
public class TestServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket =null;
InputStream is =null;
ByteArrayOutputStream bos =null;
try {
// 1. 建立socket連接
serverSocket = new ServerSocket(8080);
// 2. 等待客戶端連接過來
socket = serverSocket.accept();
// 3. 接收消息 使用IO流
is = socket.getInputStream();
// 4. 使用IO流讀取消息
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
bos.write(buffer,0,len);
}
System.out.println(bos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP
public class DatagramSocket
extends Object
DatagramSocket 類表示用來發送和接收數據報包的套接字。
public final class DatagramPacket
extends Object
DatagramPacket 類表示數據報包。數據報包用來實現無連接包投遞服務。
消息傳輸
客戶端:
public class TestClient01 {
public static void main(String[] args) {
try {
// 1. 建立一個socket
DatagramSocket socket = new DatagramSocket();
// 2. 建立一個包
String s = "信息傳輸...";
InetAddress address = InetAddress.getByName("localhost");
int port =9000;
// 數據
DatagramPacket packet = new DatagramPacket(s.getBytes(), 0, s.getBytes().length,address,port);
// 3. 發送包
socket.send(packet);
// 4. 關閉流
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
服務端:
public class TestServer01 {
public static void main(String[] args) {
try {
// 開放端口
DatagramSocket socket = new DatagramSocket(9000);
// 接收數據包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 阻塞接收
socket.receive(packet);
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
URL
public final class URL
extends Object
implements Serializable
URL類代表一個統一資源定位符,它是指向互聯網“資源”的指針,用於定位資源的、定位互聯網上的一個資源。
URL的格式:
協議://ip地址:端口/項目名/資源
public class TestURL {
public static void main(String[] args) {
try {
URL url = new URL("//http://localhost:8080/ll/SecurityFile.txt");
// 獲取端口號
System.out.println(url.getPort());
// 獲取文件
System.out.println(url.getFile());
// 獲取主機IP
System.out.println(url.getHost());
// 獲取協議
System.out.println(url.getProtocol());
// 獲取參數
System.out.println(url.getQuery());
// 獲取全路徑
System.out.println(url.getPath());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}