2.網(wǎng)絡(luò)編程
2.1. 通信協(xié)議
-
TCP、UDP對(duì)比
-
TCP 打電話
-
連接,穩(wěn)定
-
三次握手,四次揮手
三次握手 A: 你瞅啥? B: 瞅你咋地? A:干一場(chǎng)! 四次揮手 A:我要走了 B: 你真的要走了嗎? B:你真的真的要走了嗎? A:我真的要走了
-
客戶端、服務(wù)端
-
傳輸完成,釋放連接,效率低
-
-
UDP 發(fā)短信
- 不連接,不穩(wěn)定
- 客戶端,服務(wù)端,沒(méi)有明確的界限
- 不管有沒(méi)有準(zhǔn)備好,都可以發(fā)給你
- 導(dǎo)彈
- DDOS:洪水供給?。柡凸簦?/li>
-
2.2. Tcp上傳測(cè)試
1、TcpUploadClient.java
package com.hzs.basic.inet;
import java.io.*;
import java.net.Inet4Address;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
/**
* @author Cherist Huan
* @version 1.0
* @date 2021/6/8 11:39
* @note 文件上傳客戶端
*/
public class TcpUploadClient {
public static void main(String[] args) throws IOException {
// 1、創(chuàng)建一個(gè)Socket連接
Socket socket = new Socket(Inet4Address.getByName("127.0.0.1"),9999);
// 2、創(chuàng)建一個(gè)輸出流
OutputStream os = socket.getOutputStream();
// 3、讀取文件
// FileInputStream fis = new FileInputStream(new File(String.valueOf(TcpUploadClient.class.getResource("6.jpg"))));
// URL resource = TcpUploadClient.class.getResource("/images/6.jpg");
// FileInputStream fis = new FileInputStream(resource.getPath());
File file = new File("java-test-questions-06/src/main/resources/images/6.jpg");
// File file = new File("images/6.jpg");
System.out.println(file.getAbsolutePath());
FileInputStream fis = new FileInputStream(file);
// 4、寫(xiě)出文件
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer))!= -1)
{
os.write(buffer,0,len);
}
// 通知服務(wù)器,我已經(jīng)傳輸完畢了
socket.shutdownOutput(); // 我已經(jīng)傳輸完畢
// 接受服務(wù)器的響應(yīng),確定服務(wù)器接受完畢,才能關(guān)閉連接
InputStream is2 = socket.getInputStream();
byte[] buffer2 = new byte[1024];
int len2;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len2 = is2.read(buffer2))!= -1)
{
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
// 5、關(guān)閉資源
baos.close();
fis.close();
os.close();
socket.close();
}
}
2、TcpUploadServer.java
package com.hzs.basic.inet;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
/**
* @author Cherist Huan
* @version 1.0
* @date 2021/6/8 11:39
* @note 文件上傳服務(wù)端
*/
public class TcpUploadServer {
public static void main(String[] args) throws IOException {
// 1、創(chuàng)建ServerSocket
ServerSocket serverSocket = new ServerSocket(9999);
// 2、創(chuàng)建Socket監(jiān)聽(tīng)
Socket socket = serverSocket.accept();
// 3、獲取輸入流
InputStream is = socket.getInputStream();
// 4、文件輸出
// URL resource = TcpUploadClient.class.getResource("/images/6_receive.jpg");
// //FileOutputStream fos = new FileOutputStream(new File(resource.getPath()));
// FileOutputStream fos = new FileOutputStream(resource.getPath());
File file = new File("java-test-questions-06/src/main/resources/images/6receive.jpg");
//File file = new File("images/6_receive.jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer;
buffer = new byte[1024];
int len;
while((len = is.read(buffer))!= -1)
{
fos.write(buffer,0,len);
}
// 通知客戶端,我已經(jīng)接受完畢
OutputStream os = socket.getOutputStream();
os.write("服務(wù)端返回,服務(wù)端已經(jīng)接受完畢了".getBytes());
// 5、關(guān)閉資源
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
總結(jié):
-
客戶端
- 建立socket連接
- 創(chuàng)建一個(gè)輸出管道流
- 讀取需要上傳的文件
- 將文件寫(xiě)出到管道流
- 通知服務(wù)器,我已經(jīng)傳輸完畢
- 接受服務(wù)器的響應(yīng),確定服務(wù)器接受完畢,才能關(guān)閉連接
- 關(guān)閉資源
-
服務(wù)端
- 建立ServerSocker端口服務(wù)
- 創(chuàng)建Socket監(jiān)聽(tīng),返回Socket
- 獲取輸入流
- 獲取輸入流中文件輸出
- 通知客戶端,我已經(jīng)接受完畢
- 關(guān)閉資源
2.3. Udp 傳輸
1、UdpClient.java
package com.hzs.basic.inet;
import java.io.IOException;
import java.net.*;
/**
* @Author Cherist Huan
* @Date 2021/6/10 10:41
* @Version 1.0
*/
public class UdpClient {
public static void main(String[] args) throws IOException {
// System.out.println(("AB".getBytes()).length);//2
// 1、建立一個(gè)Socket
DatagramSocket socket = new DatagramSocket();
// 2、建包
String msg = "Hello Cherist Huan!";
InetAddress byName = Inet4Address.getByName("127.0.0.1");
int port = 9090;
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,byName,port);
// 3、發(fā)送包
socket.send(datagramPacket);
// 4、關(guān)閉流
socket.close();
}
}
2、UdpServer.java
package com.hzs.basic.inet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* @Author Cherist Huan
* @Date 2021/6/10 10:57
* @Version 1.0
*/
public class UdpServer {
public static void main(String[] args) throws IOException {
// 1、開(kāi)放端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
// 2、接受數(shù)據(jù)包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
datagramSocket.receive(packet);// 阻塞式接受
System.out.println(new String(packet.getData(),0,packet.getLength()));
// 關(guān)閉流
datagramSocket.close();
}
}
2.4. Udp聊天室(多線程)
1、TalkSend.java
package com.hzs.basic.inet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
/**
* @Author Cherist Huan
* @Date 2021/6/10 15:24
* @Version 1.0
*/
public class TalkSend implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private int toPort;
private String toIp;
public TalkSend(int fromPort, int toPort, String toIp) {
this.fromPort = fromPort;
this.toPort = toPort;
this.toIp = toIp;
try {
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
while(true)
{
try {
String data = reader.readLine();
byte[] dataBytes = data.getBytes();
DatagramPacket packet = new DatagramPacket(dataBytes,0,dataBytes.length,new InetSocketAddress(this.toIp,this.toPort));
socket.send(packet);
if(data.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
2、TalkReceive.java
package com.hzs.basic.inet;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* @Author Cherist Huan
* @Date 2021/6/10 15:44
* @Version 1.0
*/
public class TalkReceive implements Runnable{
DatagramSocket socket = null;
private int port;
private String msg;
public TalkReceive(int port,String msg){
this.port = port;
this.msg = msg;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
while(true){
try {
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
socket.receive(packet);//阻塞式接受包裹
// 斷開(kāi)連接 bye
byte[] data = packet.getData();
String receiveData = new String(data,0,data.length);
System.out.println(msg+":"+receiveData);
if(receiveData.equals("bye"))
{
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
3、TalkStudent.java
package com.hzs.basic.inet;
/**
* @Author Cherist Huan
* @Date 2021/6/10 15:56
* @Version 1.0
*/
public class TalkStudent {
public static void main(String[] args) {
// 開(kāi)啟兩個(gè)線程
new Thread(
new TalkSend(7777,9999,"localhost")
).start();
//學(xué)生端接受線程端口(服務(wù)端口 8888)
new Thread(
new TalkReceive(8888,"老師說(shuō)")
).start();
}
}
4、TalkTeacher.java
package com.hzs.basic.inet;
/**
* @Author Cherist Huan
* @Date 2021/6/10 16:04
* @Version 1.0
*/
public class TalkTeacher {
public static void main(String[] args) {
// 開(kāi)啟兩個(gè)線程
new Thread(
new TalkSend(6666,8888,"localhost")
).start();
//老師端接受線程端口(服務(wù)端口 9999)
new Thread(
new TalkReceive(9999,"學(xué)生說(shuō)")
).start();
}
}
2.5 對(duì)比總結(jié)
Java網(wǎng)絡(luò)編程中,TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議)是兩種主要的傳輸層協(xié)議。它們各有特點(diǎn)和適用場(chǎng)景。
TCP傳輸
特點(diǎn):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-844947.html
- 面向連接:TCP在傳輸數(shù)據(jù)之前需要先建立連接,傳輸完成后需要斷開(kāi)連接。
- 可靠傳輸:TCP通過(guò)序列號(hào)、確認(rèn)應(yīng)答、超時(shí)重傳等機(jī)制確保數(shù)據(jù)的可靠傳輸。
- 流量控制:TCP通過(guò)滑動(dòng)窗口機(jī)制進(jìn)行流量控制,避免發(fā)送方發(fā)送速率過(guò)快導(dǎo)致接收方處理不過(guò)來(lái)。
- 擁塞控制:TCP通過(guò)慢開(kāi)始、擁塞避免、快重傳、快恢復(fù)等算法進(jìn)行擁塞控制,避免網(wǎng)絡(luò)擁塞。
應(yīng)用場(chǎng)景:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-844947.html
- 需要可靠傳輸?shù)膽?yīng)用,如文件傳輸、電子郵件等。
- 對(duì)數(shù)據(jù)傳輸順序有要求的應(yīng)用,如網(wǎng)頁(yè)瀏覽、在線視頻等。
UDP傳輸
特點(diǎn):
- 無(wú)連接:UDP在傳輸數(shù)據(jù)之前不需要建立連接,每個(gè)數(shù)據(jù)報(bào)都是一個(gè)獨(dú)立的信息。
- 不可靠傳輸:UDP不保證數(shù)據(jù)的可靠傳輸,不進(jìn)行流量控制和擁塞控制。
- 開(kāi)銷(xiāo)小:由于UDP協(xié)議簡(jiǎn)單,傳輸開(kāi)銷(xiāo)小,適合實(shí)時(shí)性要求高的應(yīng)用。
應(yīng)用場(chǎng)景:
- 實(shí)時(shí)性要求高的應(yīng)用,如音頻、視頻流等。
- 允許一定程度上數(shù)據(jù)丟失的應(yīng)用,如實(shí)時(shí)游戲、實(shí)時(shí)股市行情等。
到了這里,關(guān)于Java-Java基礎(chǔ)學(xué)習(xí)(2)-網(wǎng)絡(luò)編程-TCP-UDP的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!