1.1、概述
信件:
、
打電話:---連接---接了---通話 TCP
發短信:---發送了就完事了---接收 UDP
計算機網絡:
計算機網絡是指將地理位置不同的具有獨立功能的多台計算機及其外部設備,通過通信線路連接起來,在網絡操作系統,網絡管理軟件及網絡通信協議的管理和協調下,實現資源共享和信息傳遞的計算機系統。
網絡編程的目的:
傳播交流信息,數據交換,通信。
想要達到這個效果需要什么:
1、如何准確地定位網絡上的一台主機:(端口),定位到這個計算機的某個資源。
2、找到了這個主機,如何傳輸數據呢?
javaweb:網頁編程 B/S
網絡編程:TCP/IP C/S
1.2、網絡通信的要素
如何實現網絡上的通信?
通信雙方地址:
(192.168.1.1):局域網。。
-
ip:
-
端口號
規則:網絡通信的協議:
TCP/IP參考模型:
HTTP:超文本傳輸協議
FTP:文件上傳協議
小結:
1、網絡編程中有兩個主要的問題:
-
如何准確的定位到網絡上的一台或者多台主機
-
找到主機之后如何進行通信
2、網絡編程中的要素
-
IP和端口號 IP
-
網絡通信協議 UDP,TCP
3、萬物皆對象
1.3、IP
ip地址:inetAddress
-
唯一定位一台網絡上計算機
-
127.0.0.1:本機loaclhost
-
Ip地址的分類
-
Ipv4/Ipv6
-
IPv4 127.00.1,四個字節組成,0-255,42億~;30億都在北美,亞洲四億,2011年就用盡;
-
IPV6:128位,8個無符號整數!
-
-
公網(互聯網)-私網(局域網)
-
ABCD類地址
-
192.168.xx.xx專門給組織內部使用的
-
-
-
域名:記憶IP問題!
-
IP:
-
package Second11_16;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddres {
public static void main(String[] args) {
try {
//查詢網站IP地址
InetAddress allByName = InetAddress.getByName("localhost");
System.out.println(allByName);
//常用方法:
System.out.println(allByName.getHostAddress());//IP
System.out.println(allByName.getHostName());//名字
System.out.println(allByName.getCanonicalHostName());//規范的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
1.4、端口(port)
端口表示計算機上的一個程序的進程
-
不同的進程有不同的端口號!用來區分軟件!
-
被規定0-65535
-
TCP,UDP:65536*2 tcp:80,udp:80? 單個協議下,端口不能沖突、
-
端口分類:
-
公有端口0~1023
-
HTTP:80
-
https:443
-
FTP:21
-
Telent:23
-
-
程序注冊端口:1024~49151
-
Tomcat: 8080
-
MySQL: 3306
-
Oracle: 1521
-
-
動態/私有:49152~65535
1、netstat -ano #查看所有的端口
2、netstat -ano|findstr "9640" # 查看指定的窗口 其中|是指先干后面的再在前面中找
3、tasklist|findstr "8696" #查看指定端口的進程
package Second11_16;
import java.net.InetSocketAddress;
public class TestInetSocketAddres {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(inetSocketAddress1);
System.out.println(inetSocketAddress2);
System.out.println(inetSocketAddress2.getAddress());
System.out.println(inetSocketAddress2.getHostName());//地址
System.out.println(inetSocketAddress2.getPort());//端口
}
} -
1.5、通信協議
協議:約定,就好比我們現在說的是普通話。
網絡通信協議:速率,傳輸碼率,代碼結構,傳輸控制。。。。。。
問題:非常的復雜
大事化小:分層!
TCP/IP協議簇:實際上是一層協議
重要:
-
TCP:用戶傳輸協議
-
UDP:用戶數據報協議
出名的協議:
-
TCP:
-
IP:網絡互聯協議
ps:應用層:QQ、微信;傳輸層:通信;網絡層:分包;數據鏈路層:具體的傳輸:如光纖,海底電纜。。。。。。;
TCP UDP對比:
TCP:打電話
-
連接,穩定
-
三次握手、四次揮手
最少需要三次,才能保證穩定連接!
A;你愁啥?
B:瞅你咋地?
A:干一場!
A:我要走了
B:你真的要走了嗎?
B:你真的真的要走了嗎?
A:我真的要走了! -
客戶端、服務端
-
傳輸完成,釋放連接,效率低
UDP:發短信
-
不連接,不穩定
-
客戶端、服務端:沒有明確的界限
-
不管有沒有准備好,都可以發給你。。。
-
導彈攻擊
-
DDOS:洪水攻擊!(飽和攻擊)
1.6、TCP
有關socket的知識分享:https://www.cnblogs.com/dolphinx/p/3460545.html
SeverSocket:
為了使客戶能成功地連接到服務器,服務器必須建立一個ServerSocket 對象,該對象通過將客戶端地套接字對象和服務器端地一個套接字對象連接起來,從而達到連接的目的。
客戶端:(socket對象)socket(IP地址,端口)
服務器:(ServerSocket對象)serversocket(端口 )用ServerSocket.accept()來建立一個和客戶端的Socket對象相連接的Socket對象。
服務器端的輸出流/輸入流的目的地和客戶端的輸入流/輸出流的源剛好相同。
進程堵塞
提升作用域
文件上傳
服務器端:
package lesson03;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPserver02 {
public static void main(String[] args) throws IOException {
//建立連接,創建服務
ServerSocket serverSocket= new ServerSocket(9900);
// 監聽客戶端的連接
Socket socket = serverSocket.accept();
//創立輸入流和文件輸出流
InputStream is = socket.getInputStream();
// 文件輸出
FileOutputStream fos = new FileOutputStream(new File("JTest3.png"));
//創立緩沖區和寫
byte[] buff=new byte[1024];
int len;
while((len=is.read(buff))!=-1){
fos.write(buff,0,len);
}
//與客戶端說我已經收到了
OutputStream os =socket.getOutputStream();
os.write("我已接收".getBytes());
//關閉資源
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
/*
1、接收要read,所以要用inputStream
2、要把文件寫給大家看,所以要fileoutputstream
*/
客戶端:
package lesson03;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPclient02 {
public static void main(String[] args) throws IOException {
//建立連接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9900);
//建立輸出流和文件輸入流
OutputStream os =socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("JavaKuangStudy/network programming/src/ImageData/Test.png"));
//緩沖區之后
//需要轉換格式
//寫出文件
byte[] buff = new byte[1024];//划定空間
int len;
while((len= fis.read(buff))!=-1){
os.write(buff,0,len);
}
//確定服務器接收完畢才能斷開連接。
//發送成功后關閉輸出流
//通知服務器我已經輸出結束了
socket.shutdownOutput();
//接收來自服務端的消息,用數組流來輸出
InputStream is = socket.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len1;
byte[] buff1 = new byte[1024];//初始內存空間大小
while((len1=is.read(buff1))!=-1){
bos.write(buff1,0,len1);
}
System.out.println(bos.toString());
//關閉資源
bos.close();
is.close();
fis.close();
os.close();
socket.close();
}
}
/*
1、拋出異常
2、套接字的get輸入輸出流
3、通知服務器,我已經輸出結束了:socket.shutdownOutput();
4、while((len=is.read(buff))!=-1){
bos.write(buff,0,len);
5、while和0-長度
}
*/
Tomcat
調試:consolehandler:GBK
服務端
-
自定義(S)
-
Tomcat服務器(S):Java后台開發用別人的服務器!
客戶端
-
自定義(C)
-
瀏覽器(B)
1.7、UDP
發短信:不用連接,需要知道對方的地址!
發送消息
發送端
package Udp01;
import java.net.*;
//不需要連接服務器
public class UdpTest02 {
public static void main(String[] args) throws Exception {
//建立一個socket
DatagramSocket socket=new DatagramSocket();
//建個包
InetAddress inetAddress=InetAddress.getByName("localhost");
byte[] Str= "你好".getBytes();
int port=9999;
//數據,數據的長度起始,要發送給誰
DatagramPacket datagramPacket=new DatagramPacket(Str,0,Str.length,inetAddress,port);
//發送包
socket.send(datagramPacket);
//關閉流
socket.close();
}
}
接收端:
package Udp01;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//還是要等待客戶端的鏈接
public class UdpTest01 {
public static void main(String[] args) throws Exception {
//開放端口
DatagramSocket socket=new DatagramSocket(9999);
while (true) {
//接收數據包
byte[] Strin = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(Strin, 0, Strin.length);
//阻塞接收
socket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
//關閉鏈接
socket.close();
}
}
}
咨詢
循環發送消息
發送方:
package UDP.Udp02; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; public class UdpSin { public static void main(String[] args) throws Exception { DatagramSocket datagramSocket=new DatagramSocket(8888); while (true){ //准備數據,控制台讀取System.in BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); //讀取控制台輸入的一行並把它轉化為字符 String Buf=buf.readLine(); InetAddress inetAddress=InetAddress.getByName("localhost"); DatagramPacket datagramPacket=new DatagramPacket(Buf.getBytes(),0,Buf.length(),inetAddress,9999 ); datagramSocket.send(datagramPacket); if(Buf.equals("bye")) break; } datagramSocket.close(); } } /* 1、BuffReader讀取控制台字符時用readLine來讀取一行 */
接收方:
package UDP.Udp02; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpSin01 { public static void main(String[] args) throws Exception{ //建立鏈接 DatagramSocket datagramSocket = new DatagramSocket(9999); byte[] bufin = new byte[1024]; while (true) { //准備接收包裹 DatagramPacket datagramPacket = new DatagramPacket(bufin, 0, bufin.length); datagramSocket.receive(datagramPacket);//阻塞時接收包裹 byte[] data=datagramPacket.getData(); String msg=new String(data,0,data.length); System.out.println(msg); if(msg.equals("bye")){ break; } datagramSocket.close(); } } } /* 1、創建對象 while之外 2、接收包裹.getData */
在線咨詢:兩個人都可以發送
發送端線程:
package UDP.Run; 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.InetSocketAddress; public class Sent implements Runnable{ DatagramSocket datagramSocket; DatagramPacket datagramPacket; private int fromPort; private String toIP; private int Toport; BufferedReader bufferedReader; String buf; public Sent(int fromPort, String toIP, int Toport) { this.fromPort = fromPort; this.toIP = toIP; this.Toport = Toport; try { this.datagramSocket = new DatagramSocket(fromPort); } catch (Exception e) { e.printStackTrace(); } } @Override public void run() { while(true){ try { bufferedReader=new BufferedReader(new InputStreamReader(System.in)); buf=bufferedReader.readLine(); byte[] buff=buf.getBytes(); datagramPacket= new DatagramPacket(buff,0,buff.length,new InetSocketAddress(this.toIP,this.Toport)); datagramSocket.send(datagramPacket); if (buf.equals("bye")){ break; } } catch (IOException e) { e.printStackTrace(); } } datagramSocket.close(); } } /*今日忘記 1、IP:String 2、DatagramSocket(端口) 2、BuffReader(輸入流); 3、發送要把String變成數組 */
接收端線程:
package UDP.Run; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class Receive implements Runnable{ DatagramSocket datagramSocket; DatagramPacket datagramPacket; private String FromID; private int Port; public Receive(String fromID, int port) { this.FromID = fromID; this.Port = port; try { datagramSocket=new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { try { byte[] buff = new byte[1024]; datagramPacket = new DatagramPacket(buff, 0, buff.length); datagramSocket.receive(datagramPacket); byte[] data=datagramPacket.getData(); String msg=new String(data,0,data.length); System.out.println(FromID + ":" +msg); if (datagramPacket.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } datagramSocket.close(); } } //重新定義數組
學生端:
package UDP.Run; import UDP.Run.Receive; import UDP.Run.Sent; public class Student { public static void main(String[] args) { new Thread(new Sent(7754,"localhost",9999)).start(); new Thread(new Receive("老師:",7787)).start(); } } //線程要啟動
老師端:
package UDP.Run; import UDP.Run.Receive; import UDP.Run.Sent; public class Teacher { public static void main(String[] args) { new Thread(new Sent(7755,"localhost",7787)).start(); new Thread(new Receive("學生:",9999)).start(); } }
1.8、URL
統一資源定位符:定位資源,定位互聯網上某一個資源
DNS域名解析 WWW.baidu
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class Url { public static void main(String[] args) throws IOException { URL url=new URL("https://m801.music.126.net/20201123231609/7a60a829f966abbdfc75ee0756ed0ff9/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/4916388353/e2fe/8be5/e1e6/c7614d21f4afc33120723d86e09d330d.m4a"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in=urlConnection.getInputStream(); FileOutputStream Fout=new FileOutputStream("d.m4a"); byte[] buff=new byte[1024]; int len; while ((len=in.read(buff))!=-1){ Fout.write(buff,0,len); } Fout.close(); in.close(); urlConnection.disconnect(); } }