第78節:Java中的網路程式設計(上)

標題圖
第78節:Java中的網路程式設計(上)
前言
網路程式設計涉及ip,埠,協議,tcp和udp的瞭解,和對socket通訊的網路細節.
網路程式設計

網路模型
OSI
開放系統互連

網路通訊要素
網路程式設計指IO加網路

OSI模型

TCP/IP模型

描述
TCP/IP模型:
- 應用層
- 傳輸層
- 網際層
- 主機到網路層
OSI模型:(封裝) 網路1封包->網路2拆包
- 應用層
- 表示層
- 會話層
- 傳輸層
- 網路層
- 資料鏈路層
- 物理層
網路通訊要素:
- ip地址
- 埠號
- 傳輸協議

網路通訊要素
主機名和ip地址是對應的,預設的主機名:localhost
java.net 類 InetAddress java.lang.Object -> java.net.InetAddress 已實現的介面: Serializable 已知子類: Inet4Address, Inet6Address public class InetAddress extends Object implements Serializable 該類表示網際網路協議ip地址
ip地址是ip使用32或128位無符號數字,它是一種低階的協議,UDP和TCP協議都是在它的基礎上構建的.
InetAddress的例項包含ip地址,相應的主機名
升級:
java.net 類 Inet6Address java.lang.Object -> java.net.InetAddress -> java.net.Inet6Address 所有已實現的介面:Serializable public final class Inet6Address extends InetAddress 該類表示網際網路協議第6版地址
獲取ip地址
package com.dashucoding.ip; import java.net.InetAddress; import java.net.UnknownHostException; public class IPDemo { public static void main(String[] args) throws UnknownHostException { // TODO Auto-generated method stub // ip地址物件 InetAddress // 獲取本地主機地址物件 InetAddress ip = InetAddress.getLocalHost(); // 獲取主機地址和主機名 System.out.println(ip.getHostAddress() + ":" + ip.getHostName()); InetAddress ip2 = InetAddress.getByName("192.168.2.151"); // 獲取主機地址和主機名 System.out.println(ip.getHostAddress() + ":" + ip.getHostName()); // 主機名是需要進行解析的 } }
域名解析_查表
C:\Windows\System32\drivers\etc

檔案

Internet協議屬性
DNS
域名解析伺服器,寬頻服務.配置 DNS
域名伺服器主機,一個網址瀏覽要到它的Ip地址,要找到,就會把ip地址放到 DNS
域名解析伺服器,供給本地使用寬頻連線的使用,就可以在瀏覽器中找到ip地址,瀏覽網址了.
裝 DNS
伺服器軟體,把你要瀏覽的地址ip寫進去就可以了
有些軟體需要進行註冊序列號?
// hosts 檔案配置 127.0.0.1 www.###.cn // 該域名地址
埠
埠,為物理埠,一臺電腦傳送資訊給另一臺電腦的軟體,傳送ip地址完, 要帶上埠號, 然後 對應另一臺接收訊息的軟體 有個軟體應用程式的數字標識,為邏輯埠, 這樣就可以對應傳送到另一臺電腦上的對應軟體接收訊息.
我今天要去一家酒店去了地址,到了樓層, 要知道哪個房間號,才知道對應做什麼事.

埠號
傳輸協議
TCP和UDP: 傳輸協議,傳輸規則,通訊規則,傳輸層.

TCP和UDP
UDP
,不需要建立連線.我發給你資訊,不管你在不在,我就發給你了.我送你東西,寫個地址,發到你家就行.有個包,裝東西,有大小限制,最多是64k的限制資料.(好處,速度快,不可靠)
TCP
發資料,要確保連線是不是暢通的. TCP
是通過三次握手完成的,確保資料的連線暢通.用流行的話語:
完成了三次TCP握手:
女朋友發給男朋友
:"在嗎?"
男朋友回覆女朋友
:"我在!"
女朋友回覆男朋友
:"我知道了"
這樣愛情可靠,但是很浪費時間的,這樣維護情感有點耗時,但是很可靠.
TCP
斷開就不傳了, UDP
不管.電話來形容TCP,對講機來形容UDP.
Socket

Socket
Socke <-> Socket
資料在兩者之間通過IO傳輸,傳輸協議TCP或UDP
Socket就像兩端插口,傳輸協議不一樣,Socket插口也是由不同的型別的.資料在兩者之間進行傳輸,資料是基於網路的io流進行傳輸的,傳輸過程就是傳入和傳出的過程
UDP_傳送端_out
java.net Class DatagramSocket java.lang.Object -> java.net.DatagramSocket All Implemented Interfaces: Closeable, AutoCloseable 已知直接子類: MulticastSocket public class DatagramSocket extends Object implements Closeable 該類為用於傳送和接收資料報資料包的套接字,資料報套接字是分組傳送服務的傳送或接收點.
例子:
DatagramSocket s = new DatagramSocket(null); s.bind(new InetSocketAddress(8888)); DatagramSocket s = new DatagramSocket(8888);
構造方法摘要
方法 | 說明 |
---|---|
DatagramSocket() |
構造資料報套接字並將其繫結到本地主機上的任何可用埠 |
DatagramSocket(DatagramSocketImpl impl) |
使用指定的 DatagramSocketImpl 建立一個未繫結的資料報套接字 |
DatagramSocket(int port) |
構造資料報套接字並將其繫結到本地主機上的指定埠 |
DatagramSocket(int port, InetAddress laddr) |
建立一個數據報套接字,繫結到指定的本地地址 |
DatagramSocket(SocketAddress bindaddr) |
建立一個數據報套接字,繫結到指定的本地套接字地址 |
receive(DatagramPacket p)
:從此套接字接收資料報包
send(DatagramPacket p)
:從此套接字傳送資料報包
java.net Class DatagramPacket java.lang.Object -> java.net.DatagramPacket public final class DatagramPacket extends Object 該類表示資料報包 將資料封裝到資料包中,資料包物件為DatagramPacket
資料包
DatagramPacket(byte[] buf, int length) // 位元組陣列來的
構造一個 DatagramPacket
用於接收長度的資料包 length
.
receive public void receive(DatagramPacket p) throws IOException 此套接字接收資料報包 返回, DatagramPacket的緩衝區填充了接收的資料 資料報包也包含傳送的ip地址和傳送方的埠號

傳送端

接收端
UDPSend
package com.dashucoding.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class UDPSend { public static void main(String[] args) throws IOException { System.out.println("udp 傳送端 run"); // 先建立upd的socket 面向物件程式設計 // 將資料封裝到資料包中 // 使用Socket物件的send方法 // 將資料包傳送出去 // 關閉資源 DatagramSocket ds = new DatagramSocket(); // 資料 String text = "我是傳送端,傳送的資料"; // 將資料轉成位元組陣列 byte[] buf = text.getBytes(); // 將位元組資料封裝到資料包中 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("你的ip地址"),10000); // 傳送 ds.send(dp); // 發完關掉,不然留著資源幹嘛 ds.close(); } }
package com.dashucoding.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class UDPRece { public static void main(String[] args) throws IOException { System.out.println("udp 接收端 run"); // 定義udp接收資料,顯示在螢幕上 // 先有插座嘛,udpsocket服務 // 接收資料前 -> 先將資料儲存到資料包中 // 先定義資料包 // 資料包物件會獲取資料包中的內容,傳送端的ip和埠 // 關閉資源 // 有upsocket服務 DatagramSocket ds = new DatagramSocket(10000); // 接收資料,接收位元組資料 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); // 關閉資源 ds.close(); } }
鍵盤錄入
傳送端:
package com.dashucoding.udp2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class UDPSend2 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub System.out.println("udp2 傳送端 run"); DatagramSocket ds = new DatagramSocket(); // 資料來源於鍵盤錄入 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("你的ip地址"), 10002); ds.send(dp); // 發完關掉,不然留著資源幹嘛 } ds.close(); } }
接收端:
package com.dashucoding.udp2; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class UDPRece2 { public static void main(String[] args) throws IOException { // 有upsocket服務 System.out.println("udp2 接收端 run"); DatagramSocket ds = new DatagramSocket(10002); while (true) { // 接收資料,接收位元組資料 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); // 關閉資源 } // ds.close(); } }
群聊工程
變化ip地址192.168.1.255
TCP
Socket() 通過系統預設型別的SocketImpl建立未連線套接字 Socket(InetAddress address, int port) 建立一個流套接字並將其連線到指定ip地址的指定埠 Socket(String host, int port) 建立一個流套接字並將其連線到指定主機上的指定埠號 getOutputStream() 返回此套接字的輸出流
網路程式設計 TCP 服務端

結構
package com.dashucoding.tcp; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class TCPClient { public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub // 建立tcp的客戶端socket 明確服務端的地址和埠 // socket io流 // 獲取socket流 System.out.println("客戶端執行"); // 建立tcp的客戶端socket,明確服務端的地址和埠 Socket s = new Socket("ip地址",20003); // socket輸出流資料傳送 OutputStream out = s.getOutputStream(); // 通過socket輸出流將資料傳送 out.write("hello tcp 來了".getBytes()); // 關閉 s.close(); } }
package com.dashucoding.tcp; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class TCPServer { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 獲取客戶端的資料,在螢幕上 // 思路 // 建立服務端的socket,明確埠,監聽一個埠 // 服務端只要獲取到連結過來的客戶端就可以和指定的客戶端通訊了 // 通過獲取客戶端的讀取流物件讀取客戶端發來的資料. // 顯示螢幕上 System.out.println("服務端執行"); // 建立服務端的socket,明確接收埠 ServerSocket ss = new ServerSocket(20003); while (true) { // 服務端只要獲取到連線過來的客戶端就可以和指定的客戶端通訊 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "...connected"); // 通過獲取客戶端的讀取流物件讀取客戶端傳送來的資料 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(); } // ss.close(); } }
客戶端和服務端互動
客戶端:
package com.dashucoding.tcp2; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class TCPClient2 { public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub // 實現客戶端和服務端的收發過程 System.out.println("客戶端2 啟動"); // 建立客戶端的socket物件 Socket s = new Socket("ip地址",20004); // 傳送資料,通過socket輸出流完成 OutputStream out = s.getOutputStream(); out.write("服務端,我來了".getBytes()); // 讀取服務端返回的資料,通過socket輸入流 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(); } }
服務端:
package com.dashucoding.tcp2; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class TCPServer2 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub System.out.println("服務端2 啟動"); // 建立tcp服務端socket明確埠 ServerSocket ss = new ServerSocket(20004); while (true) { // 獲取客戶端 Socket s = ss.accept(); System.out.println(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); // 給客戶端回饋資料 OutputStream out = s.getOutputStream(); out.write("客戶端,我已經收到".getBytes()); // 關閉客戶端 s.close(); } // 關閉服務端 // ss.close(); } }

客戶端

服務端
小結
網路程式設計到網路模型:一開始7層到4層
傳輸層的瞭解
網路通訊:
- ip:用於網路中主機的數字標識
- 埠:用於應用程式的數字標識
- 傳輸協議:用於資料傳輸的規則
TCP和UDP的區別
TCP: 面向連線,三次握手,速度慢,可靠
UDP: 面向無連線,速度快,不可靠
實現UDP的通訊:
可以傳送,又可以接收 DatagramSocket DatagramPacket 資料包物件
實現TCP傳輸:
客戶端,服務端
客戶端要明確服務端的ip+埠,而服務端要明確埠,通過accept的方法獲取客戶端物件.
結言
那麼你是否掌握了,什麼是tcp和udp,socket通訊機制,以及ip,埠,協議.
達叔小生:往後餘生,唯獨有你
You and me, we are family !
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: 達叔小生
https://www.jianshu.com/u/c785ece603d1結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊