1 計算機網絡
是指將地理位置不同的具有獨立功能的多臺計算機及其外部設備,通過通信線路連接起來,在網絡操作系統,網絡管理軟件及網絡通信協議的管理和協調下,實現資源共享和信息傳遞的計算機系統。
2 網絡編程
就是用來實現網絡互連的不同計算機上運行的程序間可以進行數據交換。
3 網絡編程三要素
IP
每個設備在網絡中的唯一標識
每臺網絡終端在網絡中都有一個獨立的地址,我們在網絡中傳輸數據就是使用這個地址。
IP地址的分類:IPv4 & IPv6
IPv4
IPv4:4個字節組成,4個0-255。大概42億,30億都在北美,亞洲4億。2011年初已經用盡,IP格式: 192.168.1.168。
測試網絡連接 ping 192.168.1.68
本地迴路地址:ping 127.0.0.1(測試網卡有沒插好)
廣播地址:255.255.255.255
IP地址也分公網地址(萬維網使用)和私有地址(局域網使用),192.168.開頭的就是私有址址
IPv6:8組,每組4個16進制數。1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f(IPv6暫先不用掌握)
Port端口
端口號是每個程序在設備上的唯一標識
每個網絡程序都需要綁定一個端口號,傳輸數據的時候除了確定發到哪臺機器上,還要明確發到哪個程序,端口號範圍從0-65535
編寫網絡應用就需要綁定一個端口號,儘量使用1024以上的,1024以下的基本都被系統程序佔用了。
常用端口,面試會問
mysql: 3306
oracle: 1521
web: 80
tomcat: 8080
協議
協議是爲計算機網絡中進行數據交換而建立的規則、標準或約定的集合。
網絡傳輸方式協議有TCP&UDP
TCP(傳輸控制協議)
面向連接(三次握手),數據安全,速度略低。分爲客戶端和服務端。
三次握手: 客戶端先向服務端發起請求, 服務端響應請求, 傳輸數據
UDP(數據報傳輸協議)
面向無連接,數據不安全,速度快。不區分客戶端與服務端。
4 Socket概述
Socket翻譯過來就是套接字
網絡上具有唯一標識的IP地址和端口號組合在一起才能構成唯一能識別的標識符套接字。
通信的兩端都有Socket,網絡通信其實就是Socket間的通信。
數據在兩個Socket間通過IO流傳輸。Socket就是用來建立通信管道
Socket在應用程序中創建,通過一種綁定機制與驅動程序建立關係,告訴自己所對應的IP和port。
5 TCP通信原理圖解
2.6 UDP通信原理圖解
2.7 案例:UDP數據傳輸
實現步驟:
發送Send
創建DatagramSocket, 隨機端口號
創建DatagramPacket, 指定數據, 長度, 地址, 端口
使用DatagramSocket發送DatagramPacket
關閉DatagramSocket
接收Receive
創建DatagramSocket, 指定端口號
創建DatagramPacket, 指定數組, 長度
使用DatagramSocket接收DatagramPacket
關閉DatagramSocket
從DatagramPacket中獲取數據
案例:實現UDP的發送和接收
public static void main(String[] args) throws Exception {
// 1.發送Send
// 創建DatagramSocket, 隨機端口號
DatagramSocket sender = new DatagramSocket();
// 創建DatagramPacket【數據包】, 指定數據, 長度, 地址, 端口
String s = “你好嗎?最近很想你”;
byte[] bs = s.getBytes(“UTF-8”);
DatagramPacket packet = new DatagramPacket(bs, bs.length, Inet4Address.getByName(“192.168.1.125”), 5288);
// 使用DatagramSocket發送DatagramPacket
sender.send(packet);
// 關閉DatagramSockets
sender.close();
}
public static void main(String[] args) throws IOException {
// 2.接收Receive
// 創建DatagramSocket, 指定端口號
DatagramSocket receiver = new DatagramSocket(5288);
// 創建DatagramPacket, 指定數組, 長度
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, 1024);
// 使用DatagramSocket接收DatagramPacket
receiver.receive(packet);
// 關閉DatagramSocket
receiver.close();
// 從PackeDatagramt中獲取數據
String s = new String(buf, 0, packet.getLength(), “UTF-8”);
System.out.println(“接收到數據:” + s);
}
案例:添加鍵盤和死循環功能
public class Demo_Sender {
public static void main(String[] args) throws Exception {
// 1.發送Send
// 創建DatagramSocket, 隨機端口號
DatagramSocket sender = new DatagramSocket();
//2 Scanner
Scanner scanner = new Scanner(System.in);
while(true){
// 創建DatagramPacket【數據包】, 指定數據, 長度, 地址, 端口
System.out.println(“輸入內容:”);
String s = scanner.nextLine();
byte[] bs = s.getBytes(“UTF-8”);
DatagramPacket packet = new DatagramPacket(bs, bs.length, Inet4Address.getByName(“192.168.1.125”), 5288);
// 使用DatagramSocket發送DatagramPacket
sender.send(packet);
}
// 關閉DatagramSockets
//sender.close();
}
}
package lesson05;
public class Demo_Receiver {
public static void main(String[] args) throws IOException {
// 2.接收Receive
// 創建DatagramSocket, 指定端口號
DatagramSocket receiver = new DatagramSocket(5288);
while(true){
// 創建DatagramPacket, 指定數組, 長度
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, 1024);
// 使用DatagramSocket接收DatagramPacket
receiver.receive(packet);
// 關閉DatagramSocket
//receiver.close();
// 從PackeDatagramt中獲取數據
String s = new String(buf, 0, packet.getLength(), “UTF-8”);
System.out.println(new Date() + “接收到數據:” + s);
}
}
}
案例:使用雙線程來收發數據
public class Demo {
public static void main(String[] args) {
// 案例:UDP數據傳輸+鍵盤和循環+雙線程實現(瞭解)
new Receiver().start();
new Sender().start();
}
}
class Receiver extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
try {
// 創建DatagramSocket, 指定端口號
DatagramSocket receiver = new DatagramSocket(5288);
while (true) {
// 創建DatagramPacket, 指定數組, 長度
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, 1024);
// 使用DatagramSocket接收DatagramPacket
receiver.receive(packet);
// 關閉DatagramSocket
// receiver.close();
// 從PackeDatagramt中獲取數據
String s = new String(buf, 0, packet.getLength(), "UTF-8");
System.out.println(new Date() + "接收到數據:" + s);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
class Sender extends Thread {
@Override
public void run() {
try {
// 創建DatagramSocket, 隨機端口號
DatagramSocket sender = new DatagramSocket();
//2 Scanner
Scanner scanner = new Scanner(System.in);
while(true){
// 創建DatagramPacket【數據包】, 指定數據, 長度, 地址, 端口
System.out.println(“輸入內容:”);
String s = scanner.nextLine();
byte[] bs = s.getBytes(“UTF-8”);
DatagramPacket packet = new DatagramPacket(bs, bs.length, Inet4Address.getByName(“192.168.1.125”), 5288);
// 使用DatagramSocket發送DatagramPacket
sender.send(packet);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
2.8 案例:TCP數據傳輸【多練】
》客戶端用鍵盤+死循環實現
public class Demo_Client {
public static void main(String[] args) throws IOException {
//1.創建Socket對象
Socket socket = new Socket("192.168.1.125", 9999);
//2.獲取輸入流出
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintWriter pw = new PrintWriter(os);
//3.發送數據給服務端面
pw.write("Java 還是不錯的...\r\n");
pw.flush();
//4.讀服務響應的數據
System.out.println("讀取響應數據:" + br.readLine());
//關流
br.close();
socket.close();
}
}
public class Demo_Server {
public static void main(String[] args) throws Exception {
//1.創建個服務端Socket對象,綁定端口
ServerSocket serverSocket = new ServerSocket(9999);
//2.監聽客戶端面連接
while(true){
Socket clientSocket = serverSocket.accept();
//3.接收客戶端面發送的數據
new Thread(){
public void run() {
try {
//讀寫數據都是通過IO
InputStream is = clientSocket.getInputStream();
OutputStream os = clientSocket.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintWriter pw = new PrintWriter(os);
while(true){
//讀取客戶端的數據
String line = br.readLine();
if(line != null){
System.out.println(clientSocket + ":" + new Date() + "接收到客戶端發送的數據:" + line);
//響應客戶端面
pw.write("receiver success\r\n");
pw.flush();
}
}
} catch (Exception e) {
// TODO: handle exception
}
};
}.start();
}
}
}