java多線程實現(xiàn)服務(wù)器端與多客戶端之間的通信
用java語言構(gòu)建一個網(wǎng)絡(luò)服務(wù)器,實現(xiàn)客戶端和服務(wù)器之間通信,實現(xiàn)客戶端擁有獨立線程,互不干擾。
應(yīng)用多線程來實現(xiàn)服務(wù)器與多線程之間的通信的基本步驟
- 服務(wù)器端創(chuàng)建ServerSocket,循環(huán)調(diào)用accept()等待客戶端鏈接
- 客戶端創(chuàng)建一個Socket并請求和服務(wù)器端鏈接
- 服務(wù)器端接受客戶端請求,創(chuàng)建socekt與該客戶端建立專線鏈接
- 建立鏈接的socket在一個單獨的線程上對話
- 服務(wù)器繼續(xù)等待新的鏈接
服務(wù)器端Server.java
package test.concurrent.socket;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by dong on 15-6-22.
* 基于TCP協(xié)議的Socket通信,實現(xiàn)用戶登錄
* 服務(wù)器端
*/
public class Server {
public static void main(String[] args) {
try {
//1、創(chuàng)建一個服務(wù)器端Socket,即ServerSocket, 指定綁定的端口,并監(jiān)聽此端口
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = null;
//記錄客戶端的數(shù)量
int count = 0;
System.out.println("***服務(wù)器即將啟動,等待客戶端的鏈接***");
//循環(huán)監(jiān)聽等待客戶端的鏈接
while (true){
//調(diào)用accept()方法開始監(jiān)聽,等待客戶端的鏈接
socket = serverSocket.accept();
//創(chuàng)建一個新的線程
ServerThread serverThread = new ServerThread(socket);
//啟動線程
serverThread.start();
count++; //統(tǒng)計客戶端的數(shù)量
System.out.println("客戶端的數(shù)量: " + count);
InetAddress address = socket.getInetAddress();
System.out.println("當前客戶端的IP : " + address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服務(wù)器端線程處理類ServerThread.java
package test.concurrent.socket;
import java.io.*;
import java.net.Socket;
/**
* Created by dong on 15-6-22.
* 服務(wù)器端線程處理類
*/
public class ServerThread extends Thread {
//和本線程相關(guān)的Socket
Socket socket = null;
public ServerThread(Socket socket){
this.socket = socket;
}
//線程執(zhí)行的操作,響應(yīng)客戶端的請求
public void run(){
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
//獲取一個輸入流,并讀取客戶端的信息
is = socket.getInputStream();
isr = new InputStreamReader(is); //將字節(jié)流轉(zhuǎn)化為字符流
br = new BufferedReader(isr); //添加緩沖
String info = null;
//循環(huán)讀取數(shù)據(jù)
while ((info = br.readLine()) != null){
System.out.println("我是服務(wù)器,客戶端說: " +info);
}
socket.shutdownInput(); //關(guān)閉輸入流
//獲取輸出流,響應(yīng)客戶端的請求
os = socket.getOutputStream();
pw = new PrintWriter(os); //包裝為打印流
pw.write("歡迎你");
pw.flush(); //將緩存輸出
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//關(guān)閉資源
if (pw != null)
pw.close();
if (os != null)
os.close();
if (is != null)
is.close();
if (isr != null)
isr.close();
if (br != null)
br.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客戶端Client.java
package test.concurrent.socket;
import java.io.*;
import java.net.Socket;
/**
* Created by dong on 15-6-22.
* 客戶端
*/
public class Client {
public static void main(String[] args) {
try {
//1、創(chuàng)建客戶端Socket,指定服務(wù)器端口號和地址
Socket socket = new Socket("localhost",8888);
//2、獲取輸出流,向服務(wù)器發(fā)送信息
OutputStream os = socket.getOutputStream(); //字節(jié)輸出流
PrintWriter pw = new PrintWriter(os); //將輸出流包裝為打印流
pw.write("用戶名:tom; 密碼:456");
pw.flush();
socket.shutdownOutput(); //關(guān)閉輸出流
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String info = null;
//循環(huán)讀取
while ((info = br.readLine()) != null){
System.out.println("我是客戶端:服務(wù)器說:" + info);
}
br.close();
is.close();
isr.close();
pw.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java?json轉(zhuǎn)換實體類(JavaBean)及實體類(JavaBean)轉(zhuǎn)換json代碼示例
這篇文章主要介紹了兩種常見的JSON與Java實體類相互轉(zhuǎn)換的方法,分別是使用庫Jackson、Gson、Fastjson和在線工具,無論是將JSON轉(zhuǎn)換為Java實體類還是將Java實體類轉(zhuǎn)換為JSON,這些方法都能顯著簡化開發(fā)過程,需要的朋友可以參考下2024-12-12
Java SiteMesh新手學(xué)習(xí)教程代碼案例
這篇文章主要介紹了Java SiteMesh新手學(xué)習(xí)教程代碼案例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
java springboot的概述、特點與構(gòu)建介紹
大家好,本篇文章主要講的是springboot的概述、特點與構(gòu)建介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Character.UnicodeBlock中cjk的說明詳解
這篇文章主要為大家詳細介紹了Character.UnicodeBlock中cjk的說明,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
springboot中使用ElasticSearch的詳細教程
這篇文章主要介紹了ElasticSearch在springboot中使用的詳細教程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05
Java字節(jié)緩存流的構(gòu)造方法之文件IO流
這篇文章主要介紹了Java字節(jié)緩存流的構(gòu)造方法之文件IO流,同時也介紹了字符流中的一些相關(guān)的內(nèi)容,并且通過大量的案例供大家理解。最后通過一些經(jīng)典的案例幫助大家對前面所學(xué)的知識做了一個綜合的應(yīng)用,需要的朋友可以參考一下2022-04-04
mybatisplus如何解決分頁最多500條數(shù)據(jù)
這篇文章主要介紹了mybatisplus如何解決分頁最多500條數(shù)據(jù)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
將本地SpringBoot項目發(fā)布到云服務(wù)器的方法
這篇文章主要介紹了如何將本地SpringBoot項目發(fā)布到云服務(wù)器,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12

