JAVA - 基於Socket的多執行緒通訊
程式碼簡介
程式碼思想:
實現"服務端-客戶端"之間的通訊需要解決兩點問題
(1),如何實現通訊
(2),通訊中如何避免單執行緒先接收後傳送(或先傳送後接收)的問題;
解決方案:
(1),實現通訊:使用ServerSocket監聽指定埠後,Socket進行連線;然後客戶端與服務端都獲取Socket物件的輸入輸出流存入PrintWrite後不斷重新整理,即可實現通訊;
(2),彌補單執行緒缺陷:建立訊息接收類和訊息傳送類分別繼承Thread;然後透過開啟兩個執行緒完避免單執行緒必須先接收後傳送(或先傳送後接收)的問題;
詳細程式碼如下,如有最佳化,歡迎留言:
服務端
package x_Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class x_Server{
/** 宣告全域性物件,讓x_Server的內部類可以共同呼叫這些物件 **/
static ServerSocket serverSocket = null;//宣告靜態全域性的socket類物件;讓x_Server的靜態方法可以直接呼叫該物件;
static Socket socket = null; //宣告靜態全域性的socket類物件;讓x_Server的靜態方法可以直接呼叫該物件;
BufferedReader buffSend = null; //資訊傳送資料流
BufferedReader buffReciever = null; //資訊接收資料流
PrintWriter printWriter = null; //資料讀寫資料流
/** 主函式入口 **/
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(5556); //透過Socket的建構函式,監聽的5556埠(即等待socket物件向該埠請求連線)
socket = serverSocket.accept(); //如果有socket的物件請求連線了5556埠,則serverSocket的accept返回一個socket物件;
System.out.println("有使用者成功連線客戶端");
Thread xsend = new Thread(new x_Server().new x_Send()); //透過Thread類的建構函式,建立一個x_Send類的執行緒物件
Thread xreciver = new Thread(new x_Server().new x_Receiver()); //透過外部類物件去例項化內部類,再透過Thread的建構函式,建立內部類x_Reciever的執行緒二物件;
xsend.start(); //啟動x_Send的執行緒,讓傳送與接收資料可以同時進行
xreciver.start(); //啟動x_Receiver的執行緒,讓傳送與接收資料可以同時進行
}
/** 用於服務端傳送資訊的x_Send類(執行緒一) **/
class x_Send extends Thread{
public void run(){ //繼承Thread類,必須重寫run()方法
try {
buffSend = new BufferedReader(new InputStreamReader(System.in));//獲取從控制檯輸入資料的物件buffSend
printWriter = new PrintWriter(socket.getOutputStream()); //透過PrintWriter類的構造方法,獲取向客戶端傳送資訊的輸出流物件
String msg = null; //msg:儲存服務端傳送的資訊
do{
msg = buffSend.readLine(); //獲得從控制檯輸入一行的資訊
printWriter.println(msg); //將msg傳到向服務端傳送資訊的輸出流物件
printWriter.flush(); //重新整理輸入輸出流,客戶端端可以立刻收到輸入輸出流的更新資訊
}while(!msg.equals("end")); //客戶輸入"end"表示結束通訊
socket.close(); //關閉埠5556的連線
serverSocket.close(); //不再監聽埠5556(即不再接收來自該埠的連線)
} catch (IOException e) {
System.out.println("客戶端連線已斷開");
e.printStackTrace();
}
}
}
/** 用於服務端接收資訊的x_Reciever類(執行緒二) **/
class x_Receiver extends Thread{
public void run(){ //繼承Thread類,必須重寫run()方法
try {
buffReciever = new BufferedReader(new InputStreamReader(socket.getInputStream())); //獲取從socket輸入(客戶端傳輸過來)資料的輸入流物件
while(true){
System.out.println("接收客戶端訊息:"+buffReciever.readLine()); //輸出客戶端傳輸過來的資訊
}
} catch (IOException e) {
System.out.println("客戶端連線已斷開:\n");
e.printStackTrace();
}
}
}
}
客戶端
package x_Socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class x_Client {
/** 宣告全域性物件,讓x_Client的內部類可以共同呼叫這些物件 **/
static Socket socket = null; //宣告靜態全域性的socket類物件;讓x_Client的靜態方法可以直接呼叫該物件;
BufferedReader buffSend = null; //資訊傳送資料流
BufferedReader buffReciever = null; //資訊接收資料流
PrintWriter printWriter = null; //資料讀寫資料流
/** 主函式入口 **/
public static void main(String[] args) throws UnknownHostException, IOException {
socket =new Socket("127.0.0.1",5556); //透過Socket的建構函式,連線本地ip的5556埠
System.out.println("連線服務端資訊如下:\nip:127,0.0.1 port:5556");
Thread xsend = new Thread(new x_Client().new x_SendMsg()); //透過Thread類的建構函式,建立一個x_SendMsg類的執行緒物件
Thread xreciver = new Thread(new x_Client().new x_RecieverMsg()); //透過外部類物件去例項化內部類,再透過Thread的建構函式,建立內部類x_RecieverMsg的執行緒二物件;
xsend.start(); //啟動x_SendMsg的執行緒;
xreciver.start(); //啟動x_RecieverMsg的執行緒;兩個讓傳送與接收資料可以同時進行
}
/** 用於客戶端傳送資訊的x_SendMsg類(執行緒一)**/
class x_SendMsg extends Thread{
public void run(){ //繼承Thread類,必須重寫run()方法
try {
buffSend = new BufferedReader(new InputStreamReader(System.in));//獲取從控制檯輸入資料的物件buffSend
printWriter = new PrintWriter(socket.getOutputStream()); //透過PrintWriter類的構造方法,獲取向服務端傳送資訊的輸出流物件
String msg = null; //msg:儲存客戶端傳送的資訊
do{
msg = buffSend.readLine(); //獲得從控制檯輸入一行的資訊
printWriter.println(msg); //將msg傳到向服務端傳送資訊的輸出流物件
printWriter.flush(); //重新整理輸入輸出流,服務端可以立刻收到輸入輸出流的更新資訊
}while(!msg.equals("end")); //客戶輸入"end"表示結束通訊
socket.close(); //關閉埠5556的連線
} catch (IOException e) {
System.out.println("服務端埠已關閉"); //異常提示資訊顯示
e.printStackTrace();
}
}
}
/** 用於客戶端接收資訊的x_RecieverMsg類(執行緒二) **/
class x_RecieverMsg extends Thread{
public void run(){ //繼承Thread類,必須重寫run()方法
try {
buffReciever = new BufferedReader(new InputStreamReader(socket.getInputStream())); //獲取從socket輸入(服務端傳輸過來)資料的輸入流物件
while(true){
System.out.println("收到服務端訊息:"+buffReciever.readLine()); //輸出服務端傳輸過來的資訊
}
} catch (IOException e) {
System.out.println("服務端埠已關閉"); //異常提示資訊顯示
e.printStackTrace();
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69979119/viewspace-2710192/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java socket 通訊socketServer 服務端多執行緒JavaServer服務端執行緒
- Java多執行緒-執行緒通訊Java執行緒
- java多執行緒5:執行緒間的通訊Java執行緒
- Java多執行緒學習——執行緒通訊Java執行緒
- java多執行緒間的通訊Java執行緒
- Java多執行緒學習(3)執行緒同步與執行緒通訊Java執行緒
- Java多執行緒技術:實現多使用者服務端Socket通訊Java執行緒服務端
- 【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAllJava執行緒AI
- java多執行緒實現TCP網路Socket程式設計(C/S通訊)Java執行緒TCP程式設計
- Java執行緒通訊Java執行緒
- Java多執行緒中的wait/notify通訊模式Java執行緒AI模式
- java多執行緒基礎知識速通Java執行緒
- 多執行緒之間的通訊執行緒
- Java之執行緒通訊Java執行緒
- 多執行緒之間通訊及執行緒池執行緒
- Android小知識-Java多執行緒相關(執行緒間通訊)上篇AndroidJava執行緒
- java多執行緒:執行緒間通訊——生產者消費者模型Java執行緒模型
- 多執行緒Demo學習(執行緒的同步,簡單的執行緒通訊)執行緒
- java - 多執行緒基礎Java執行緒
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- Java 多執行緒學習(執行緒通訊——消費者和生產者)Java執行緒
- Java多執行緒學習(五)執行緒間通訊知識點補充Java執行緒
- Java 多執行緒基礎(八)執行緒讓步Java執行緒
- Java多執行緒-基礎篇Java執行緒
- Java 多執行緒基礎 - CyclicBarrierJava執行緒
- Java中的執行緒通訊詳解Java執行緒
- 自己開發的線上視訊下載工具,基於Java多執行緒Java執行緒
- Java執行緒(九):Condition-執行緒通訊更高效的方式Java執行緒
- python中的socket+threading多執行緒Pythonthread執行緒
- Java多執行緒—執行緒同步(單訊號量互斥)Java執行緒
- Swift多執行緒:使用Thread進行多執行緒間通訊,協調子執行緒任務Swift執行緒thread
- 關於Java多執行緒的執行緒同步和執行緒通訊的一些小問題(順便分享幾篇高質量的博文)Java執行緒
- Java多執行緒-執行緒中止Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 說說Java執行緒間通訊Java執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- Java多執行緒消費訊息Java執行緒