TCP使用Socket進行網絡通信的過程:
- 伺服器程式将一個套接字綁定到一個特定的端口,并通過此套接字等待和監聽來自用戶端的連接配接請求;
- 用戶端根據伺服器所在的主機名和端口向伺服器發送連接配接請求;
- 如果一切正常,伺服器接收連接配接請求,并獲得一個新的綁定到不同端口位址的套接字;
- 用戶端和伺服器通過讀寫套接字進行通訊。
UDP使用Socket進行網絡通信的過程
- UDP協定通信沒有用戶端(浏覽器)/伺服器模式,通信的雙方是平等的;
- 每個UDP建立都有獨立的端口号綁定。程式設計時對獨立的一個端點程式設計,使其同時具有發送接收的方法;
- 與TCP協定程式設計不同,UDP收發資料不用I/O流。
基于TCP協定的Socket程式設計
TCP服務端:
1. 建立一個ServerSocket對象;
2. 調用accept()方法接收用戶端請求;
3. 從Socket中擷取I/0流;
4. 對I/0進行讀寫操作,完成與用戶端的互動。
TCP用戶端:
1. 建立一個Socket對象;
2. 從Socket中擷取I/0流;
4. 對I/0進行讀寫操作,完成與用戶端的互動;
5. 關閉I/O流和Socket。
伺服器程式設計:接收用戶端傳來的位元組流,轉化成字元流,再轉化成大寫,傳回伺服器。
import java.net.ServerSocket;
public class TCPServer{
public static void main(String[] args){
//1.建立一個ServerSocket對象
ServerSocket serverSocket=new ServerSocket();
//2.調用accept()方法來接受用戶端請求
Socket socket=serverSocket.accept();
System.out.println(socket.getInetAddress().getHostAddress()+"has connected");//表示某台網絡裝置與伺服器連接配接成功
//3.從Socket對象中擷取I/0流;
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
'''BufferedWriter bw=new BufferedWriter(new OutputSreamWriter(socket.getOutputStram()));'''
//自動重新整理緩沖區
PrintWriter pw=new PrintWriter(socket.getOutputStream().true);
//把用戶端傳過來的位元組流轉換成字元流
String line=null;
while(line=br.readline()!=null){
if(line.equals("over")){
break;
}
System.out.println(line);
'''''
bw.write(line.toUpperCase());//把轉換成大寫的字元串傳給用戶端。
bw.newLine();//換行,标志着一段字元輸入完畢,用戶端readLine才會确認輸入完畢
bw.flush();//清空緩沖區
'''''
pw.println(line.toUpperCase());
}
//釋放資源
'''bw.close();'''
pw.close();
br.close();
socket.close();
System.out.println(socket.getInetAddress().getHostAddress()+"has disconnected");//表示某台網絡裝置與伺服器連接配接斷開
}
}
用戶端程式設計:用戶端傳輸鍵盤輸入給伺服器,再讀取從伺服器傳回的大寫字元串
import java.net.Socket;
public class TCPClient{
public static void main(String[] args) throws IOExceprion{
//1.建立一個Socket對象;
Socket socket=new Socket("127.0.0.1",);
//讀取鍵盤輸入的位元組流
BufferedReader br=new BufferedReader(new InputStramReader(System.in));
//對I/0進行讀寫操作,完成與用戶端的互動;
//把鍵盤輸入的位元組流存入socket的buffer中向伺服器發送
BufferedWriter bw=new BufferedWriter(new OutputSreamWriter(socket.getOutputStram()));
//從socket的buffer中讀取伺服器傳來的位元組流
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String line=br.readLine();//從鍵盤不斷輸入的字元串
bw.write(line);
bw.newLine();//換行,标志着一段字元輸入完畢,服務端readLine才會确認輸入完畢
bw.flush;
if(line.equals("over")){
break;
}
//讀取從服務端傳來的字元
System.out.println(reader.readline());
}
//釋放資源
reader.close();
br.close();
bw.close();
socket.close();
}
}
執行:分别打開兩個DOS視窗,第一個先運作伺服器程式,第二個運作用戶端程式
基于UDP協定的Socket程式設計
建立發送端
1. 建立DatagramSocket對象,該端點建立,系統會随機配置設定一個端口,也可以手動指定;
2. 将資料進行packet包的封裝,必須要指定目的位址和端口;
3. 通過socket服務的send方法将該包發出;
4. 将socket 關閉。
建立接收端
1. 建立DatagramSocket對象,要監聽一個端口;
2. 通過socket的receive方法将擷取資料包;
3. 通過資料包dp的方法 getData()、getAddress()、getPort()等方法,擷取包中的資訊;
4. 将socket關閉。
UDP端點程式設計:
發送端
import java.net InetAddress;
import java.net DatagramSocket;
import java.net DatagramPacket;
public class UDPDemo1{
public static void main(String[] args) throw IOException{
//1. 建立DatagramSocket對象,該端點建立,系統會随機配置設定一個端口;
DatagramSocket socket=new DatagramSocket();
//2. 發送資料,将資料進行packet包的封裝,必須要指定目的位址和端口;
String str="I love studying";
DatagramPacket packet=new DatagramPacket(str.getBytes(),str.length,InetAddress.getByName("localhost"),);
//參數清單:【發送資料】【發送資料的長度】【接收端主機的位址】【接收端口号】
//3. 通過socket服務的send方法将該包發出;
socket.send(packet);
//4. 通過socket的receive方法将擷取資料包,存入一個數組;
byte[] buff=new byte[];
DatagramPacket packet2=new DatagramPacket(buff,);
socket.receive(packet2);
//5.通過資料包dp的方法 getData()把接受的位元組數組轉換成字元串
System.out.println(new String(packet2.getData()));
//6. 将socket 關閉
socket.close();
}
}
接收端
import java.net InetAddress;
import java.net DatagramSocket;
import java.net DatagramPacket;
public class UDPDemo2{
public static void main(String[] args) throw IOException {
//1. 建立DatagramSocket對象,該端點建立,手動指定端口;
DatagramSocket socket=new DatagramSocket();
//2. 通過socket的receive方法将擷取資料包,存入一個數組;
byte[] buff=new byte[];
'''''
DatagramPacket packet=new DatagramPacket(buff,100);
//當接收字元長度不夠100時會出現多餘的字元
'''''
DatagramPacket packet=new DatagramPacket(buff,,packet.getLength());
socket.receive(packet);
//3.通過資料包dp的方法 getData()把接受的位元組數組轉換成字元串
System.out.println(new String(packet.getData()));
//4. 發送資料,将資料進行packet包的封裝,必須要指定目的位址和端口;
String str="Study makes my happy!";
DatagramPacket packet2=new DatagramPacket(str.getBytes(),str.length,packet.getAddress(),packet.getPort());
//【接收端主機的位址】【接收端口号】可以根據之前接收到的packet擷取
//5. 通過socket服務的send方法将該包發出;
socket.send(packet2);
//6. 将socket 關閉
socket.close();
}
}