java多線程實(shí)現(xiàn)服務(wù)器端與多客戶端之間的通信
用java語(yǔ)言構(gòu)建一個(gè)網(wǎng)絡(luò)服務(wù)器,實(shí)現(xiàn)客戶端和服務(wù)器之間通信,實(shí)現(xiàn)客戶端擁有獨(dú)立線程,互不干擾。
應(yīng)用多線程來(lái)實(shí)現(xiàn)服務(wù)器與多線程之間的通信的基本步驟
- 服務(wù)器端創(chuàng)建ServerSocket,循環(huán)調(diào)用accept()等待客戶端鏈接
- 客戶端創(chuàng)建一個(gè)Socket并請(qǐng)求和服務(wù)器端鏈接
- 服務(wù)器端接受客戶端請(qǐng)求,創(chuàng)建socekt與該客戶端建立專線鏈接
- 建立鏈接的socket在一個(gè)單獨(dú)的線程上對(duì)話
- 服務(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通信,實(shí)現(xiàn)用戶登錄 * 服務(wù)器端 */ public class Server { public static void main(String[] args) { try { //1、創(chuàng)建一個(gè)服務(wù)器端Socket,即ServerSocket, 指定綁定的端口,并監(jiān)聽(tīng)此端口 ServerSocket serverSocket = new ServerSocket(8888); Socket socket = null; //記錄客戶端的數(shù)量 int count = 0; System.out.println("***服務(wù)器即將啟動(dòng),等待客戶端的鏈接***"); //循環(huán)監(jiān)聽(tīng)等待客戶端的鏈接 while (true){ //調(diào)用accept()方法開(kāi)始監(jiān)聽(tīng),等待客戶端的鏈接 socket = serverSocket.accept(); //創(chuàng)建一個(gè)新的線程 ServerThread serverThread = new ServerThread(socket); //啟動(dòng)線程 serverThread.start(); count++; //統(tǒng)計(jì)客戶端的數(shù)量 System.out.println("客戶端的數(shù)量: " + count); InetAddress address = socket.getInetAddress(); System.out.println("當(dāng)前客戶端的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)客戶端的請(qǐng)求 public void run(){ InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; OutputStream os = null; PrintWriter pw = null; try { //獲取一個(gè)輸入流,并讀取客戶端的信息 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ù)器,客戶端說(shuō): " +info); } socket.shutdownInput(); //關(guān)閉輸入流 //獲取輸出流,響應(yīng)客戶端的請(qǐ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ù)器端口號(hào)和地址 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ù)器說(shuō):" + info); } br.close(); is.close(); isr.close(); pw.close(); os.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java并發(fā)編程(CyclicBarrier)實(shí)例詳解
這篇文章主要介紹了Java并發(fā)編程(CyclicBarrier)實(shí)例詳解的相關(guān)資料,JAVA編寫并發(fā)程序的時(shí)候,我們需要仔細(xì)去思考一下并發(fā)流程的控制,如何讓各個(gè)線程之間協(xié)作完成某項(xiàng)工作。2017-07-07微信支付java版V3驗(yàn)證數(shù)據(jù)合法性(Deom)
這篇文章主要介紹了微信支付java版V3驗(yàn)證數(shù)據(jù)合法性(Deom)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例
這篇文章主要介紹了SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java中讀寫鎖ReadWriteLock的原理與應(yīng)用詳解
Java并發(fā)編程提供了讀寫鎖,主要用于讀多寫少的場(chǎng)景,今天我們就重點(diǎn)來(lái)講解讀寫鎖ReadWriteLock的原理與應(yīng)用場(chǎng)景,感興趣的可以了解一下2022-09-09基于python locust庫(kù)實(shí)現(xiàn)性能測(cè)試
這篇文章主要介紹了基于python locust庫(kù)實(shí)現(xiàn)性能測(cè)試,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05詳解Java中的字節(jié)碼增強(qiáng)技術(shù)
字節(jié)碼增強(qiáng)技術(shù)就是一類對(duì)現(xiàn)有字節(jié)碼進(jìn)行修改或者動(dòng)態(tài)生成全新字節(jié)碼文件的技術(shù)。本文將通過(guò)示例詳細(xì)說(shuō)說(shuō)Java的字節(jié)碼增強(qiáng)技術(shù),需要的可以參考一下2022-10-10完美解決Get和Post請(qǐng)求中文亂碼的問(wèn)題
下面小編就為大家?guī)?lái)一篇完美解決Get和Post請(qǐng)求中文亂碼的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05Java內(nèi)存區(qū)域與內(nèi)存溢出異常詳解
這篇文章主要介紹了Java內(nèi)存區(qū)域與內(nèi)存溢出異常詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03