感謝! 承蒙關照~java
探索Java中的網絡編程技術編程
網絡編程就是io
技術和網絡技術的結合,網絡模型的定義,只要共用網絡模型就能夠二者鏈接.網絡模型參考.數組
一座塔有七層,咱們須要闖關.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層
端口
傳輸協議
TCP``UDP
TCP和UDP的區別:
TCP: 面向鏈接,經過三次握手完成,速度慢,可靠。 UDP: 面向無鏈接,速度快,不可靠。
UDP
是將數據及其源和目的封裝成數據包中,不須要創建鏈接,每一個數據報的大小在限制在64k
內,因無鏈接,是不可靠的協議,不須要鏈接,可是速度快.
TCP
是須要進行鏈接的,造成傳輸數據的通道,在鏈接中進行大數據量傳輸,經過三次握手完成鏈接,是可靠的協議,效率低便是速度慢一點.
網絡編程-Socket
網絡通信的要素:
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…