第62節:探索Java中的網絡編程技術

標題圖

前言

感謝! 承蒙關照~java

探索Java中的網絡編程技術編程

網絡編程就是io技術和網絡技術的結合,網絡模型的定義,只要共用網絡模型就能夠二者鏈接.網絡模型參考.數組

osi模型

TCP/IP參考模型

一座塔有七層,咱們須要闖關.bash

第一層物理層->第二層數據鏈路層->第三層網絡層->第四層傳輸層->第五層會話層->第六層表示層->第七層應用層.網絡

物理層是主要定義物理設備標準,數據鏈路層是主要講從物理層接收的數據進行MAC地址(網卡的地址)的封裝與解封裝.這層的數據較幀.socket

網絡層是將從下層接收到的數據進行IP地址的封裝和解封裝.傳輸層是定義一些傳輸數據的協議和端口號.tcp

會話層是將經過傳輸層創建數據傳輸的通路.表示層是進行對接收的數據進行解釋,加密與解密.ide

應用層主要是一些終端的應用.大數據

應用層 --> 傳輸層 --> 網絡層 --> 主機至網絡層ui

效果

效果

電腦通信要點: 一須要IP地址:InetAddress(互聯網協議便是規則) 二須要端口號 三須要傳輸協議

IP地址,網絡中設備的標識,不容易記住,能夠用主機名,本地迴環地址: 127.0.0.1 主機名就是 localhost了.所謂局域網就是局部範圍內的,互聯網就是全球的.

端口號是用來標識進程的邏輯地址,不一樣進行的標識,有效的端口爲0到65535,其中0到1024系統使用或保留的端口.

傳輸協議便是通信的規則,常見的協議爲TCP, UDP.

java.net

InetAddress

java.lang.Object
-> java.net.InetAddress
複製代碼

全部已實現的接口有:

Serializable
複製代碼

直接已知子類:

Inet4Address, Inet6Address
複製代碼
public class InetAddress extends Object implements Serializable
複製代碼

這個類表示互聯網協議已地址.

效果

地址類型

Class Inet6Address

java.lang.Object
java.net.InetAddress
java.net.Inet6Address
複製代碼
public final class Inet6Address extends InetAddress
複製代碼

效果

獲取ip地址:

public class IPDemo {
 public static void main(String[] args) throws UnknownHostException {
  //獲取本地主機地址對象
  InetAddress ip = InetAddress.getLocalHost();
  System.out.println(ip.getHostAddress() + ":" + ip.getHostName());
 }
}
複製代碼

域名解析

C:\WINDOWS\system32\drivers\etc
複製代碼

InetAddress方法

類型 方法 說明
boolean equals(Object obj) 將此對象與指定對象進行比較
byte[] getAddress() 返回此InetAddress對象的原始ip地址.
static InetAddress[] getAllByName(String host) 給定主機的名稱,根據系統上配置的名稱服務返回其ip地址數組.
static InetAddress getByAddress(byte[] addr) 給出原始IP地址的InetAddress對象
static InetAddress getByAddress(String host, byte[] addr) 根據提供的主機名和ip地址建立InetAddress
static InetAddress getByName(String host) 肯定主機名稱的ip地址
String getCanonicalHostName() 獲取此ip地址的徹底限定域名
String getHostAddress() 返回文本顯示中的ip地址字符串
String getHostName() 獲取此ip地址的主機名

網絡編程:

1,網絡模型:7層--->4層

端口

  1. 用於標識進程的邏輯地址,不一樣進程的標識
  2. 有效端口:0到65535,而0到1024系統使用或保留端口

傳輸協議

常見協議TCP``UDP

TCP和UDP的區別:

TCP: 面向鏈接,經過三次握手完成,速度慢,可靠。 UDP: 面向無鏈接,速度快,不可靠。

UDP是將數據及其源和目的封裝成數據包中,不須要創建鏈接,每一個數據報的大小在限制在64k內,因無鏈接,是不可靠的協議,不須要鏈接,可是速度快.

TCP是須要進行鏈接的,造成傳輸數據的通道,在鏈接中進行大數據量傳輸,經過三次握手完成鏈接,是可靠的協議,效率低便是速度慢一點.

網絡編程-Socket

網絡通信的要素:

  1. ip
  2. 端口
  3. 傳輸協議

ip是用於標識網絡中主機的數字標識,而端口是用於標識應用程序的數字,還有傳輸協議是用於進行數據傳輸的規則.

實現UDP的通訊,TCP傳輸:客戶端,服務端.

Socket是網絡服務提供的一種機制,是通訊兩端必備的,都要有Socket,網絡通訊其實就是Socket間的通訊,數據在兩個Socket間經過io傳輸.

兩端發送端和接收端-UDP

UDP發送端Demo

public class UDPSend{
 public static void main(String[] args){
  System.out.println("udp發送端");
 }
}
複製代碼

DatagramSocket

public class DatagramSocket extends Object
複製代碼

此類表示用來發送和接收數據報包的套接字.

數據報套接字是包投遞服務的發送或接收點.每一個在數據報套接字上發送或接收的包都是單獨編址和路由的.從一臺機器發送到另外一臺機器的多個包可能選擇不一樣的路由,也可能按不一樣的順序到達.

DatagramSocket上老是啓動UDP廣播發送.爲了接收廣播包,將DatagramSocket綁定到通配符地址.

效果

void receive(DatagramPacket p)
今後套接字接收數據報包
send(DatagramPacket p)
今後套接字發送數據報包
複製代碼
public class UDPSend{
 public static void main(String[] args) throws IOException{
  System.out.println("udp發送端");
  DatagramSocket ds = new DatagramSocket();
  String text = "hello";
  byte[] buf = text.getBytes();
  // 將數據轉成字節數組
  DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("123.23232.323.2"),10000);
  ds.send(dp);
  ds.close();
 }
}
// 創建upd的socket,具有發送或接收功能
// 將數據封裝到數據包中,數據包對象是DatagramPacket.
// 使用socket對象的send方法將數據包發出去.
// 關閉資源
複製代碼

udp接收端

public class updDemo {
 public static void main(String[] args) throws IOException {
  System.out.println("udp 接收端");
  // 先有udpsocket服務
  // 接收數據
  DatagramSocket ds = new DatagramSocket();
  byte[] buf = new byte[1024];
  DatagramPacket dp = new DatagramPacket(buf, buf.length);
  ds.receive(dp);
  String ip = dp.getAddress().getHostAddress();
  int port = dp.getPort():
  String text = new String(dp.getData(),0,dp.getLength());
  // 關閉資源。
  ds.close();
 }
}
複製代碼

receive

public void receive(DatagramPacket p) throws IOException
此套接字接收數據報包
複製代碼

實現UDP的通訊,udp傳輸涉及的兩個對象,便可以發送,又能夠接收.TCP傳輸:客戶端,服務端.

UDP鍵盤輸入

public class UDPSend {
	public static void main(String[] args) throws IOException {
		System.out.println("udp 發送端 run");
//		1,創建udp的socket它具有者發送或者接收功能。
		DatagramSocket ds = new DatagramSocket(9999);
//		2,將數據封裝到數據包中。數據包對象是DatagramPacket。數據來自於鍵盤錄入。
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		while((line=bufr.readLine())!=null){
			if("over".equals(line)){
				break;
			}
			byte[] buf = line.getBytes();//將數據轉成字節數組。
//			將字節數組封裝到數據包中。
			DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.223"), 10001);
//			3,使用socket對象的send方法將數據包發送出去。
			ds.send(dp);
		}
//		4,關閉資源。
		ds.close();
	}
}
複製代碼
public class UDPRece {
	public static void main(String[] args) throws IOException {
		System.out.println("udp2 接收端 run");
		DatagramSocket ds = new DatagramSocket(10001);
		while (true) {
			// 2,接收數據。
			// 3,先定義數據包。
			byte[] buf = new byte[1024];
			DatagramPacket dp = new DatagramPacket(buf, buf.length);
			ds.receive(dp);
			// 4,經過數據包對象獲取數據包的內容,發送端的ip。發送端的端口,發送過來的數據。
			String ip = dp.getAddress().getHostAddress();
			int port = dp.getPort();
			String text = new String(dp.getData(), 0, dp.getLength());

			System.out.println(ip + ":" + port + ":" + text);
		}
		// 5,關閉資源。
//		ds.close();
	}
}
複製代碼

案例:

public class UDPChatTest {
	public static void main(String[] args) throws IOException {
		//發送端的socket 接收端的socket
		DatagramSocket sendSocket = new DatagramSocket();
		DatagramSocket receSocket = new DatagramSocket(10002);
		
		//建立任務對象。
		Send send = new Send(sendSocket);
		Rece rece = new Rece(receSocket);
		
		//建立線程並開啓。
		Thread t1 = new Thread(send);
		Thread t2 = new Thread(rece);
		t1.start();
		t2.start();
	}

}

// 發送任務
class Send implements Runnable {

	private DatagramSocket ds;

	public Send(DatagramSocket ds) {
		super();
		this.ds = ds;
	}

	@Override
	public void run() {
		try {
			BufferedReader bufr = new BufferedReader(new InputStreamReader(
					System.in));
			String line = null;
			while ((line = bufr.readLine()) != null) {
				byte[] buf = line.getBytes();// 將數據轉成字節數組。
				DatagramPacket dp = new DatagramPacket(buf, buf.length,
						InetAddress.getByName("1928.1.223"), 10002);
				ds.send(dp);
				if ("886".equals(line)) {
					break;
				}
			}

			// 4,關閉資源。
			ds.close();
		} catch (IOException e) {

		}
	}
}

// 接收任務。
class Rece implements Runnable {

	private DatagramSocket ds;

	public Rece(DatagramSocket ds) {
		super();
		this.ds = ds;
	}

	@Override
	public void run() {
		while (true) {

			try {
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);
				ds.receive(dp);// 阻塞
				
				String ip = dp.getAddress().getHostAddress();
				int port = dp.getPort();
				String text = new String(dp.getData(), 0, dp.getLength());
				System.out.println(ip + ":" + port + ":" + text);
				if(text.equals("886")){
					System.out.println(ip+"....離開聊天室");
				}
			} catch (IOException e) {

			}
		}

	}

}
複製代碼

tcp案例:

public class TCPClient {
	public static void main(String[] args) throws IOException {
		System.out.println("客戶端運行.......");
//		1,創建tcp的客戶端socket。明確服務端的地址和端口。
		Socket s = new Socket("192.1.223",10003);
//		2,若是通道創建成功就會出現socket io流。
//			客戶端須要作的就獲取socket流的中輸出流將數據發送目的地服務端。
		OutputStream out = s.getOutputStream();
//		3,經過socket輸出流將數據發送。
		out.write("hello tcp 來了!".getBytes());
//		4,關閉資源。
		s.close();
	}
}
複製代碼
public class TCPServer {
	public static void main(String[] args) throws IOException {
		System.out.println("服務端開啓.....");
		ServerSocket ss = new ServerSocket(10003);
		while (true) {
			Socket s = ss.accept();
			String ip = s.getInetAddress().getHostAddress();

			InputStream in = s.getInputStream();
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String text = new String(buf, 0, len);
			System.out.println(text);
			s.close();
		}
	}
}
複製代碼

案例:

public class TCPClient2 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("客戶端2 啓動.......");
		Socket s = new Socket("192.1623", 10004);
		OutputStream out = s.getOutputStream();
		out.write("服務端,我來了".getBytes());
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(text);
//		關閉資源。
		s.close();
	}
}
複製代碼
public class TCPSever2 {
	public static void main(String[] args) throws IOException {
		System.out.println("服務端2啓動.....");
		ServerSocket ss = new ServerSocket(10004);
		while (true) {
			// 獲取客戶端對象。
			Socket s = ss.accept();
			// 讀取客戶端的發送過來的數據
			InputStream in = s.getInputStream();
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String text = new String(buf, 0, len);
			System.out.println(text);
			// 給客戶端回饋數據。
			OutputStream out = s.getOutputStream();
			out.write("客戶端,我已到收到,哦耶!".getBytes());
			// 關閉客戶端
			s.close();
		}
		// 關閉服務端。若是不斷的獲取客戶端,不用關閉服務端。
//		ss.close();
	}
}
複製代碼

達叔小生:日後餘生,惟獨有你 You and me, we are family ! 90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動而且善於溝通 簡書博客: 達叔小生 www.jianshu.com/u/c785ece60…

結語

  • 下面我將繼續對 其餘知識 深刻講解 ,有興趣能夠繼續關注
  • 小禮物走一走 or 點贊
相關文章
相關標籤/搜索