第78節:Java中的網絡編程(上)java
網絡編程涉及ip,端口,協議,tcp和udp的瞭解,和對socket通訊的網絡細節.編程
OSI
開放系統互連數組
網絡編程指IO加網絡瀏覽器
TCP/IP模型:bash
OSI模型:(封裝) 網絡1封包->網絡2拆包服務器
網絡通信要素:網絡
主機名和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
複製代碼
DNS
域名解析服務器,寬帶服務.配置DNS
域名服務器主機,一個網址瀏覽要到它的Ip地址,要找到,就會把ip地址放到DNS
域名解析服務器,供給本地使用寬帶鏈接的使用,就能夠在瀏覽器中找到ip地址,瀏覽網址了.
裝DNS
服務器軟件,把你要瀏覽的地址ip寫進去就能夠了
有些軟件須要進行註冊序列號?
// hosts 文件配置
127.0.0.1 www.###.cn // 該域名地址
複製代碼
端口,爲物理端口,一臺電腦發送信息給另外一臺電腦的軟件,發送ip地址完, 要帶上端口號, 而後 對應另外一臺接收消息的軟件 有個軟件應用程序的數字標識,爲邏輯端口, 這樣就能夠對應發送到另外一臺電腦上的對應軟件接收消息.
我今天要去一家酒店去了地址,到了樓層, 要知道哪一個房間號,才知道對應作什麼事.
TCP和UDP: 傳輸協議,傳輸規則,通信規則,傳輸層.
UDP
,不須要創建鏈接.我發給你信息,無論你在不在,我就發給你了.我送你東西,寫個地址,發到你家就行.有個包,裝東西,有大小限制,最可能是64k的限制數據.(好處,速度快,不可靠)
TCP
發數據,要確保鏈接是否是暢通的.TCP
是經過三次握手完成的,確保數據的鏈接暢通.用流行的話語:
完成了三次TCP握手:
女友發給男友 :"在嗎?"
男友回覆女友 :"我在!"
女友回覆男友 :"我知道了"
這樣愛情可靠,可是很浪費時間的,這樣維護情感有點耗時,可是很可靠.
TCP
斷開就不傳了,UDP
無論.電話來形容TCP,對講機來形容UDP.
Socke <-> Socket
數據在二者之間經過IO傳輸,傳輸協議TCP或UDP
Socket就像兩端插口,傳輸協議不同,Socket插口也是由不一樣的類型的.數據在二者之間進行傳輸,數據是基於網絡的io流進行傳輸的,傳輸過程就是傳入和傳出的過程
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層
傳輸層的瞭解
網絡通信:
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…