第78節:Java中的網絡編程(上)

標題圖

第78節:Java中的網絡編程(上)java

前言

網絡編程涉及ip,端口,協議,tcp和udp的瞭解,和對socket通訊的網絡細節.編程

網絡編程

網絡模型

OSI開放系統互連數組

網絡通信要素

網絡編程指IO加網絡瀏覽器

OSI模型

TCP/IP模型

描述

TCP/IP模型:bash

  1. 應用層
  2. 傳輸層
  3. 網際層
  4. 主機到網絡層

OSI模型:(封裝) 網絡1封包->網絡2拆包服務器

  1. 應用層
  2. 表示層
  3. 會話層
  4. 傳輸層
  5. 網絡層
  6. 數據鏈路層
  7. 物理層

網絡通信要素:網絡

  1. ip地址
  2. 端口號
  3. 傳輸協議

網絡通信要素

主機名和ip地址是對應的,默認的主機名:localhostsocket

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協議都是在它的基礎上構建的.tcp

InetAddress的實例包含ip地址,相應的主機名ui

升級:

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層

傳輸層的瞭解

網絡通信:

  1. ip:用於網絡中主機的數字標識
  2. 端口:用於應用程序的數字標識
  3. 傳輸協議:用於數據傳輸的規則

TCP和UDP的區別

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

實現UDP的通訊:

能夠發送,又能夠接收 DatagramSocket DatagramPacket 數據包對象
複製代碼

實現TCP傳輸:

客戶端,服務端

客戶端要明確服務端的ip+端口,而服務端要明確端口,經過accept的方法獲取客戶端對象.

結言

那麼你是否掌握了,什麼是tcp和udp,socket通訊機制,以及ip,端口,協議.

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

結語

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