关于TCP/IP协议及网络通信相关问题
一、網絡模型:
OSI標準模型七層架構以及其傳輸數據的模型如下:
?
傳輸信息的過程由上之下逐漸封裝,接收過程則是由下至上逐漸拆包,每一層只解析自己獨立的部分。
二、網絡的機要素
1、IP
1 public class NetTest { 2 public static void main(String[] args) throws UnknownHostException { 3 //獲取本地ip 4 InetAddress ip = InetAddress.getLocalHost(); 5 System.out.println(ip); 6 } 7 }?
2、域名
本地ip和域名映射文件? :? C:\Windows\System32\drivers\etc\hosts
?
當用戶訪問的是服務器對應的域名時候,首先會在本地該映射文件中找,如果沒有,則訪問第三方廠商提供的域名解析器進行解析,最終將域名解析為ip地址進行訪問。如下圖:
?
?
3、端口port
為了能夠實現應用程序之間的通訊,引入端口來區分。例如飛秋和qq之間的通訊。
4、傳輸層協議
傳輸層協議有一下幾個TCP 、UDP 、 TLS 、 DCCP 、 SCTP 、RSVP 、 PPTP,常用的有TCP和UDP。
?
?UDP:
面向無連接;將數據及源和和目的封裝成包,不需要建立連接;每一個數據包的大小限制在64kb以內;不需要連接,因此速度快;不安全(例如qq發送消息)。
TCP:
需要建立連接,形成傳輸通道;在連接中進行大量的數據傳輸;通過三次握手完成連接,是安全可靠的;同比效率較低(例如用qq傳遞文件)。
5、網絡傳輸中的重要概念Soket
它是為通訊提供的一種機制;通信的兩端都有Soket;網絡通訊的實質就是Soket之間的通訊;數據在兩個Soket之間及進行IO傳輸。
?
?6、UDP
UDP傳輸如同碼頭、船、集裝箱和貨物一樣;發送的信息如同貨物,DatagramPacket就是集裝箱,多大的貨物就要用對應的集裝箱;傳輸協議如同船只,soket就是碼頭。接收端必須要有明確的端口。然后用自己的DatagramPacket(集裝箱去封裝貨物)。代碼和步驟如下:
1 //基于UDP傳輸協議的多人聊天示例 2 public class UdpChat { 3 public static void main(String[] args) throws Exception { 4 DatagramSocket dsk = new DatagramSocket(); 5 DatagramSocket res = new DatagramSocket(10001);//接收方必須有固定端口 6 Send_Port send = new Send_Port(dsk); 7 Resive_Port resv = new Resive_Port(res); 8 new Thread(send).start();; 9 new Thread(resv).start();; 10 } 11 } 12 13 /* 14 * 發送端 15 */ 16 class Send_Port implements Runnable{ 17 /* 18 * 步驟: 19 * 1、創建UDP的Soket,使其具備發送能力; 20 * 2、創建及封裝需要傳輸的數據; 21 * 3、使用Soket的send方法進行發送; 22 * 4、關閉資源。 23 */ 24 25 //該對象用于發送 26 private DatagramSocket dsk; 27 public Send_Port(DatagramSocket sp) { 28 super(); 29 this.dsk = sp; 30 } 31 @Override 32 public void run() { 33 //鍵盤輸入文本 34 BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 35 String line = null; 36 System.out.println("請輸入:"); 37 try { 38 while((line = bf.readLine()) != null) { 39 if("886".equals(line)) { 40 System.out.println("發送方終止通話"); 41 break; 42 } 43 byte[] bt = line.getBytes(); 44 /*參數:需要傳輸的數據;數據長度,接收方的ip地址,接收方的端口號*/ 45 DatagramPacket packg = new DatagramPacket(bt, bt.length, InetAddress.getByName("172.16.10.255"), 10001); 46 dsk.send(packg); 47 } 48 dsk.close();//關閉資源 49 } catch (IOException e) { 50 e.printStackTrace(); 51 } 52 } 53 } 54 55 /* 56 * 接收端 57 */ 58 class Resive_Port implements Runnable{ 59 /* 60 * 步驟: 61 * 1、創建UDP的Soket,用于接收 62 * 2、創建接受包,用于接收傳遞來的數據,其中需要規定接收專用的集合及其大小 63 * 3、接收數據 64 * 4、關閉資源。 65 */ 66 private DatagramSocket drk; 67 //初始化參數 68 public Resive_Port(DatagramSocket drk) { 69 super(); 70 this.drk = drk; 71 } 72 @Override 73 public void run() { 74 byte[] res_byte = new byte[1024]; 75 DatagramPacket res = new DatagramPacket(res_byte , res_byte.length);//相當于集裝箱。 76 while(true) { 77 try { 78 drk.receive(res); 79 String text = new String(res.getData(),0,res.getData().length); 80 if(text!=null) { 81 DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 82 String date = df.format(new Date()); 83 if("886".equals(text)) { 84 System.out.println("用戶:"+res.getAddress()+"退出群聊!"); 85 } 86 System.out.println(res.getAddress()+":"+text); 87 System.out.print(date); 88 } 89 } catch (IOException e) { 90 e.printStackTrace(); 91 } 92 } 93 } 94 }?
7、TCP
面向連接,詳情人如下:
1 public class TCPTest { 2 /** 3 * 服務端編程思想:(開啟后將處于阻塞狀態) 4 * 1、創建服務端Socket,監聽一個明確的端口; 5 * 2、獲取客戶端對象(不用自己創建流) 6 * 3、根據客戶端對象獲取到對應的輸入流,讀取客戶端發來數據 7 * 4、邏輯處理 8 * 5、 9 * @throws Exception 10 */ 11 public static void main(String[] args) throws Exception { 12 13 //服務端socket,監聽一個端口 14 ServerSocket ss = new ServerSocket(10003); 15 Service ser = new Service(ss); 16 ser.server(); 17 } 18 } 19 20 class test{ 21 /** 22 * 客戶端編程思路: 23 * 1、創建客戶端Soket,明確服務端的地址和端口。 24 * 2、三次握手,建立通道,如果通道建立成功,客戶端和服務器就會形成Soke IO流。 25 * 客戶端的任務就是獲取到Socket中的輸出流將,將信息傳輸服務器中。 26 * 3、通過輸出流發送數據 27 * 4、關閉資源 28 * 29 * 注意事項:面向連接編程首先應該先啟動服務器,這樣客戶端才能夠像服務器發送請求 30 */ 31 public static void main(String[] args) throws Exception { 32 //客戶端socket,明確服務端ip和port 33 Socket s = new Socket(InetAddress.getByName("172.16.10.23"),10003); 34 Client cl = new Client(s); 35 cl.client(); 36 } 37 } 38 39 class Client{ 40 /*客戶端socket*/ 41 private Socket client_socket; 42 /* 初始化參數 */ 43 public Client(Socket client_socket) { 44 super(); 45 this.client_socket = client_socket; 46 } 47 public void client() throws Exception { 48 OutputStream out = null; 49 try { 50 System.out.println("客戶端開始請求資源"); 51 out = client_socket.getOutputStream(); 52 out.write("請求資源".getBytes()); 53 } catch (IOException e) { 54 throw new Exception("連接超時:"+ e); 55 }finally{ 56 out.close(); 57 } 58 } 59 } 60 61 class Service{ 62 private ServerSocket service ; 63 public Service(ServerSocket service) { 64 super(); 65 this.service = service; 66 } 67 /*阻塞狀態*/ 68 public void server() throws Exception { 69 System.out.println("服務器初始化完成..."); 70 //獲取客戶端 71 Socket client = service.accept(); 72 if(client!=null) { 73 //從客戶端中獲取輸入流 74 InputStream in = client.getInputStream(); 75 //讀取 76 byte[] bt = new byte[1024]; 77 int line = in.read(bt); 78 String text = new String(bt,0,line); 79 String ip = client.getInetAddress().getHostAddress(); 80 System.out.println(ip+":"+text); 81 client.close(); 82 } 83 } 84 }?
?
轉載于:https://www.cnblogs.com/L-W-T/p/7728844.html
總結
以上是生活随笔為你收集整理的关于TCP/IP协议及网络通信相关问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [数位dp] bzoj 3209 花神的
- 下一篇: prop attr 到底哪里不一样?