java網路通訊之Socket通訊:TCP/UDP
阿新 • • 發佈:2018-11-27
網路通訊三要素:協議,IP,埠。七層協議。
package com.qianfeng.test; /* * 網路程式設計基礎: * 網路的通訊:三要素:協議,IP,埠 * 1.IP:在網路上唯一的標記一臺主機 127.0.0.1 :保留地址/本地地址 java將IP面向物件了形成的類叫InetAddress * 2.埠:一臺主機上的多個伺服器 取值範圍(0,65535) 注意:在通訊時要保證客戶端和伺服器端使用的埠號一致 * 3.協議:制定的一個統一的標準 * * * 七層協議: 瞭解 * 應用層 與其它計算機進行通訊的一個應用,它是對應應用程式的通訊服務的。 例如,一個沒有通訊功能的字處理程式就不能執行通訊的程式碼, 從事字處理工作的程式設計師也不關心OSI的第7層。但是,如果添加了一個 傳輸檔案的選項,那麼字處理器的程式設計師就需要實現OSI的第7層。 示例:TELNET,HTTP,FTP,NFS,SMTP等。 表示層 這一層的主要功能是定義資料格式及加密。例如,FTP允許你選擇以二進位制 或ASCII格式傳輸。如果選擇二進位制,那麼傳送方和接收方不改變檔案的內容。 如果選擇ASCII格式,傳送方將把文字從傳送方的字符集轉換成標準的ASCII後 傳送資料。在接收方將標準的ASCII轉換成接收方計算機的字符集。示例:加密,ASCII等。 會話層 它定義瞭如何開始、控制和結束一個會話,包括對多個雙向訊息的控制和管理, 以便在只完成連續訊息的一部分時可以通知應用,從而使表示層看到的資料是連續的, 在某些情況下,如果表示層收到了所有的資料,則用資料代表表示層。示例:RPC,SQL等。 傳輸層 這層的功能包括是否選擇差錯恢復協議還是無差錯恢復協議,及在同一主機上對不同 應用的資料流的輸入進行復用,還包括對收到的順序不對的資料包的重新排序功能。 示例:TCP,UDP,SPX。 網路層 這層對端到端的包傳輸進行定義,它定義了能夠標識所有結點的邏輯地址,還定義了 路由實現的方式和學習的方式。為了適應最大傳輸單元長度小於包長度的傳輸介質, 網路層還定義瞭如何將一個包分解成更小的包的分段方法。示例:IP,IPX等。 資料鏈路層 它定義了在單個鏈路上如何傳輸資料。這些協議與被討論的各種介質有關。示例:ATM,FDDI等。 物理層 OSI的物理層規範是有關傳輸介質的特性標準,這些規範通常也參考了其他組織制定的標準。 連線頭、幀、幀的使用、電流、編碼及光調製等都屬於各種物理層規範中的內容。 物理層常用多個規範完成對所有細節的定義。示例:Rj45,802.3等。 */ public class Demo5 { }
InetAddress類
package com.qianfeng.test; import java.net.InetAddress; import java.net.UnknownHostException; public class Demo6 { public static void main(String[] args) throws UnknownHostException { //IP地址 :java面向物件後形成的類InetAddress //獲取自己的主機 InetAddress inetAddress1 = InetAddress.getLocalHost(); System.out.println(inetAddress1.getHostName());//LAPTOP-47K4STIG System.out.println(inetAddress1.getHostAddress());//192.168.124.1 //獲取網路上任意一臺主機 InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com"); System.out.println(inetAddress2.getHostName());//www.baidu.com System.out.println(inetAddress2.getHostAddress());//220.181.112.244 } }
網路通訊之Socket通訊:UDP客戶端
package com.qianfeng.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /* * 網路通訊之Socket通訊:TCP/UDP * * TCP與UDP通訊的區別: * TCP UDP * 1.是建立在連線的基礎上 建立在非連線的基礎上 * 2.安全性更高 安全性低 * 3.傳輸速度低 速度高 * 4.適合傳輸資料量大的資料 資料量小的資料 * * 客戶端:(app/瀏覽器) * 伺服器端:!=主機 * * 埠號:同一臺主機上的每一個伺服器都擁有自己的埠號,取值範圍(0,65535),常用的埠:80,8080 * 注意點:1.要保證客戶端和伺服器端的埠號一致 2.要保證同一臺主機上的不同伺服器埠號不同 * *先講解UDP 注意:要先開啟伺服器端,再開啟客戶端。 *客戶端 *實現過程: * 1.建立UDP通訊的物件--socket物件,對應的類是DatagramSocket(用於UDP通訊資料的傳送和接收) * 2.資料的封裝--裝包(打包),DatagramPacket(資料包,包括相關的屬性,資料等) * 3.傳送--呼叫send方法 * 4.關閉相關資源 * */ public class Demo7 { public static void main(String[] args) throws IOException { // * 1.建立UDP通訊的物件--socket物件,對應的類是DatagramSocket(用於UDP通訊資料的傳送和接收) DatagramSocket socket = new DatagramSocket(); // * 2.資料的封裝--裝包(打包),DatagramPacket(資料包,包括相關的屬性,資料等) /* * 第一個引數:包的內容 * 第二個:資料的長度 * 第三個:伺服器的主機物件 * 第四個:伺服器的埠 */ byte[] buf = "bingbing".getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 20000);//埠與伺服器端一致 // * 3.傳送--呼叫send方法 socket.send(packet); // * 4.關閉相關資源 socket.close(); } }
網路通訊之Socket通訊:UDP伺服器端
package com.qianfeng.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 伺服器端--接收資料
* 1.建立socket物件,繫結埠
* 2.建立包物件,建立空陣列,準備接收傳過來的資料
* 3.接收資料
* 4.關閉資源
*/
public class Demo8 {
public static void main(String[] args) throws IOException {
// * 1.建立socket物件,繫結埠
DatagramSocket socket = new DatagramSocket(20000);
// * 2.建立包物件,建立空陣列,準備接收傳過來的資料
byte[] buf =new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// * 3.接收資料--當伺服器運轉起來,這個方法會一直處於監聽狀態。
socket.receive(packet);
byte[] arr = packet.getData();
System.out.println(new String(arr));
//將資料從包中取出
// * 4.關閉資源
socket.close();
}
}
實現隨時發隨時收—使用UDP(客戶端)
package com.qianfeng.test;
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;
/*
* 例項:實現隨時發隨時收---使用UDP
*
* 客戶端
*/
public class Demo9 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
//獲取字元緩衝流實現從控制檯接收資料
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String data = null;
while ((data = bufferedReader.readLine()) != null) {
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 20000);//埠與伺服器端一致
//傳送
socket.send(packet);
//當用戶輸入over的時候代表結束
if (data.equals("over")) {
break;
}
}
socket.close();
}
}
實現隨時發隨時收—使用UDP(伺服器端)
package com.qianfeng.test;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 伺服器端
*/
public class Demo10 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(20000);
//實現不斷的接收資料
while (true) {
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
// * 3.接收資料--當伺服器運轉起來,這個方法會一直處於監聽狀態.
socket.receive(packet);
//將資料從包中取出
byte[] arr = packet.getData();
String data = new String(arr);
System.out.println(data);
//當用戶輸入over的時候代表結束
if (data.trim().equals("over")) {
break;
}
}
socket.close();
}
}
TCP客戶端
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* TCP:
* 客戶端
* 在客戶端與伺服器端通訊的時候,對於客戶端既要進行輸入又要進行輸出,所以在Socket物件的內部就內建了輸入流和輸出流,
* 當進行資料傳輸的時候,將資料放入socket物件的內部,將socket物件傳到伺服器端,相當於在客戶端與伺服器端建立了一個通道,
* 兩端使用同一個socket物件.
*/
public class Demo11 {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.建立Socket物件並繫結伺服器的埠和主機地址
Socket socket = new Socket(InetAddress.getLocalHost(), 30000);
//2.準備資料
String data = "BigData1715,你好";
//3.獲取Socket物件內部的輸出流
OutputStream outputStream = socket.getOutputStream();
//4.將資料寫入網路
outputStream.write(data.getBytes());
//接收從伺服器回傳的資訊
InputStream inputStream = socket.getInputStream();
byte[] arr = new byte[103];
// int num = inputStream.read(arr);
// System.out.println(new String(arr,0,num));
int num = 0;
while ((num = inputStream.read(arr)) != -1) {
System.out.println(new String(arr,0,num));
}
//5.關閉資源
//outputStream.close();
socket.close();
}
}
TCP伺服器端
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 伺服器端:
*/
public class Demo12 {
public static void main(String[] args) throws IOException {
//1.建立ServerSocket物件並繫結埠
ServerSocket serverSocket = new ServerSocket(30000);
//2.接收套接字---socket物件,accept方法會一直處於監聽狀態
Socket socket = serverSocket.accept();
//3.獲取輸入流
InputStream inputStream = socket.getInputStream();
//4.將內容寫到控制檯
byte[] arr = new byte[103];
int num = inputStream.read(arr);
System.out.println(new String(arr,0,num));
// int num = 0;
// while ((num = inputStream.read(arr)) != -1) {
// System.out.print(new String(arr,0,num));
// }
//完成資料的回傳
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好,BigData1715".getBytes());
//5.關閉資源
serverSocket.close();
}
}
TCP例項:實現大小寫轉換(客戶端)
package com.qianfeng.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* TCP例項:實現大小寫轉換
*客戶端
*
*/
public class Demo13 {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.建立Socket物件並繫結伺服器的埠和主機地址
Socket socket = new Socket(InetAddress.getLocalHost(), 30001);
//2.準備資料
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//注意:這裡最好使用原始的流
//3.獲取socket內部的輸入流與輸出流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream,true);//當第二個引數為true的時候會自動重新整理,
//當執行println、printf 或 format 方法的時候
String data = null;
while ((data = bufferedReader.readLine()) != null) {
//傳送
// outputStream.write(data.getBytes());
// outputStream.flush();
printWriter.println(data);
//接收伺服器端的資料
byte[] arr = new byte[100];
int num = inputStream.read(arr);
System.out.println(new String(arr,0,num));
//當用戶輸入over的時候代表結束
if (data.equals("over")) {
break;
}
}
socket.close();
}
}
TCP例項:實現大小寫轉換(伺服器端)
package com.qianfeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 伺服器端
*/
public class Demo14 {
public static void main(String[] args) throws IOException {
//1.建立ServerSocket物件並繫結埠
ServerSocket serverSocket = new ServerSocket(30001);
//2.接收套接字---socket物件,accept方法會一直處於監聽狀態
Socket socket = serverSocket.accept();
//3.獲取輸入流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream,true);//當第二個引數為true的時候會自動重新整理,
//當執行println、printf 或 format 方法的時候
int num=0;
byte[] arr = new byte[100];
while ((num = inputStream.read(arr)) != -1) {
//列印到控制檯
String data = new String(arr,0,num);
System.out.println(data);
//資訊回傳
//outputStream.write(data.toUpperCase().getBytes());
printWriter.println(data.toUpperCase());
//當用戶輸入over的時候代表結束
if (data.equals("over")) {
break;
}
}
serverSocket.close();
}
}