hello world

          隨筆 - 2, 文章 - 63, 評(píng)論 - 0, 引用 - 0
          數(shù)據(jù)加載中……

          如何編寫多線程Socket程序

          轉(zhuǎn)自 http://blog.csdn.net/ooppookid/article/details/51711323


          1、如何編寫多線程Socket程序

          了解Socket看這里:Socket是什么
          多線程Socket與單線程類似,只是使用了多線程的方式來(lái)管理連接,主線程負(fù)責(zé)接收連接,在接到連接后變創(chuàng)建新的線程,每個(gè)線程負(fù)責(zé)與自己的客戶端進(jìn)行通信。

          了解單線程Socket看這里:如何編寫單多線程Socket程序

          與單線程Socket例子相比來(lái)說(shuō),服務(wù)端可以與多個(gè)客戶端進(jìn)行通信了,不過(guò)多線程頻繁的創(chuàng)建與銷毀便會(huì)帶來(lái)很大的資源開(kāi)銷,而系統(tǒng)的網(wǎng)絡(luò)資源等都是有限的。因此一般會(huì)引入線程池,可以在某種程度上重用線程,減少線程的創(chuàng)建和銷毀的次數(shù)以減少開(kāi)銷

          我們的代碼也分為客戶端和服務(wù)端兩部分。服務(wù)端的代碼中包含了使用和不使用線程池的兩種方式。

          服務(wù)端代碼

          ?1?import?java.io.BufferedReader;
          ?2?import?java.io.IOException;
          ?3?import?java.io.InputStreamReader;
          ?4?import?java.io.PrintWriter;
          ?5?import?java.net.ServerSocket;
          ?6?import?java.net.Socket;
          ?7?import?java.util.concurrent.ExecutorService;
          ?8?import?java.util.concurrent.Executors;
          ?9?
          10?public?class?SocketThreadPoolDemoServer?{
          11?
          12?????private?int?port?=?8000;
          13?
          14?????private?ServerSocket?serverSocket;
          15?
          16?????private?ExecutorService?executorService;?//?連接池
          17?
          18?????private?final?int?POOL_SIZE?=?1;?//?連接池大小?,?若為?1?時(shí)最多支持?2?線程
          19?
          20?????public?SocketThreadPoolDemoServer()?throws?Exception?{
          21?????????serverSocket?=?new?ServerSocket(port);
          22?????????executorService?=?Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()?*?POOL_SIZE);//?初始化線程池
          23?????????System.out.println("waitting?connet");
          24?
          25?????}
          26?
          27?????/**
          28??????*
          29??????*?接受連接
          30??????*
          31??????*?@author?sunjie?at?2016年6月14日
          32??????*
          33??????*/
          34?????public?void?service()?{
          35?????????Socket?socket?=?null;
          36?????????while?(true)?{
          37?????????????try?{
          38?????????????????socket?=?serverSocket.accept();
          39?????????????????executorService.execute(new?Handler(socket));?//?使用連接池
          40?????????????????//?new?Thread(new?Handler(socket)).start();//?不使用連接池
          41?????????????}?catch?(IOException?e)?{
          42?????????????????e.printStackTrace();
          43?????????????}
          44?????????}
          45?????}
          46?
          47?????/**
          48??????*
          49??????*?線程類,負(fù)責(zé)維持與一個(gè)客戶端的通信
          50??????*
          51??????*?@author?sunjie?at?2016年6月14日
          52??????*
          53??????*/
          54?????class?Handler?implements?Runnable?{
          55?
          56?????????private?Socket?socket?=?null;
          57?
          58?????????public?Handler(Socket?socket)?{
          59?????????????this.socket?=?socket;
          60?????????}
          61?
          62?????????@Override
          63?????????public?void?run()?{
          64?????????????System.out.println("new?connection?accepted:"?+?socket.getInetAddress()?+?":"?+?socket.getPort());
          65?????????????try?{
          66?????????????????BufferedReader?reader?=?new?BufferedReader(new?InputStreamReader(socket.getInputStream(),?"UTF-8"));
          67?????????????????PrintWriter?writer?=?new?PrintWriter(socket.getOutputStream());
          68?????????????????String?msg?=?null;
          69?????????????????while?((msg?=?reader.readLine())?!=?null)?{
          70?????????????????????System.out.println("from?"?+?socket.getInetAddress()?+?":"?+?socket.getPort()?+?",?receive?msg:"
          71?????????????????????????????+?msg);
          72?????????????????????writer.println(msg);
          73?????????????????????writer.flush();
          74?????????????????????if?("close".equals(msg))?{
          75?????????????????????????break;
          76?????????????????????}
          77?????????????????}
          78?????????????}?catch?(IOException?e)?{
          79?????????????????e.printStackTrace();
          80?????????????}?finally?{
          81?????????????????try?{
          82?????????????????????if?(socket?!=?null)?{
          83?????????????????????????socket.close();
          84?????????????????????}
          85?????????????????}?catch?(IOException?e)?{
          86?????????????????????e.printStackTrace();
          87?????????????????}
          88?????????????}
          89?????????}
          90?????}
          91?
          92?????public?static?void?main(String[]?args)?throws?Exception?{
          93?????????new?SocketThreadPoolDemoServer().service();
          94?????}
          95?}
          96?
          97?

          運(yùn)行服務(wù)端代碼后,程序會(huì)一直進(jìn)行監(jiān)聽(tīng),直到接收到客戶端請(qǐng)求為止。結(jié)果如下:

          waitting connet…

          客戶端代碼(與單線程完全相同):

          ?1?public?class?SocketDemoClient?{
          ?2?
          ?3?????private?String?host?=?"127.0.0.1";//?要發(fā)送給服務(wù)端的ip
          ?4?
          ?5?????private?int?port?=?8000;//?要發(fā)送給服務(wù)端的端口
          ?6?
          ?7?????private?Socket?socket;
          ?8?
          ?9?????public?SocketDemoClient()?throws?Exception?{
          10?????????socket?=?new?Socket(host,?port);//?構(gòu)造Socket客戶端,并與連接服務(wù)端
          11?????}
          12?
          13?????public?void?talk()?throws?IOException?{
          14?????????try?{
          15?????????????BufferedReader?reader?=?new?BufferedReader(new?InputStreamReader(socket.getInputStream(),?"UTF-8"));
          16?????????????PrintWriter?writer?=?new?PrintWriter(socket.getOutputStream());
          17?????????????//?讀取本地控制臺(tái)的消息
          18?????????????BufferedReader?localReader?=?new?BufferedReader(new?InputStreamReader(System.in));
          19?????????????String?msg?=?null;
          20?????????????while?((msg?=?localReader.readLine())?!=?null)?{
          21?????????????????writer.println(msg);
          22?????????????????writer.flush();
          23?????????????????System.out.println("send?msg:"?+?reader.readLine());
          24?????????????????if?("close".equals(msg))?{
          25?????????????????????break;
          26?????????????????}
          27?????????????}
          28?????????}?catch?(Exception?e)?{
          29?????????????e.printStackTrace();
          30?????????}?finally?{
          31?????????????if?(socket?!=?null)?{
          32?????????????????socket.close();
          33?????????????}
          34?????????}
          35?????}
          36?
          37?????public?static?void?main(String[]?args)?throws?Exception?{
          38?????????new?SocketDemoClient().talk();
          39?????}
          40?}

          由于我們要測(cè)試多個(gè)客戶端連接同一個(gè)服務(wù)端,所以我們需要多次運(yùn)行客戶端代碼。這里我們運(yùn)行兩次之后(稱為客戶端1、客戶端2),查看服務(wù)端的Console,會(huì)出現(xiàn)以下結(jié)果,說(shuō)明已經(jīng)連接成功:

          waitting connet…
          new connection accepted:/127.0.0.1:59593
          new connection accepted:/127.0.0.1:59596

          我們?cè)谌?font color="#ff0000">客戶端1的Console中輸入我們要發(fā)送的消息”維護(hù)世界和平”,回車確定后,客戶端1的Console出現(xiàn)以下結(jié)果,消息已經(jīng)發(fā)出:

          send msg:維護(hù)世界和平

          再去客戶端2的Console中輸入”好好學(xué)習(xí)天天向上”,回車確定后,客戶端2的Console出現(xiàn)以下結(jié)果,消息已經(jīng)發(fā)出:

          send msg:好好學(xué)習(xí)天天向上

          在服務(wù)端的Console中,我們會(huì)看到如下結(jié)果,說(shuō)明兩個(gè)客戶端的消息已經(jīng)被接受

          waitting connet…
          new connection accepted:/127.0.0.1:59593
          new connection accepted:/127.0.0.1:59596
          from /127.0.0.1:59593, receive msg:維護(hù)世界和平
          from /127.0.0.1:59596, receive msg:好好學(xué)習(xí)天天向上

          posted on 2017-07-25 10:30 聽(tīng)風(fēng) 閱讀(114) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA

          主站蜘蛛池模板: 湘西| 辽宁省| 南溪县| 湖口县| 永泰县| 江都市| 介休市| 时尚| 景谷| 乌拉特中旗| 巴彦淖尔市| 洪江市| 屏边| 临沭县| 太湖县| 津市市| 环江| 汾西县| 福州市| 定远县| 平潭县| 襄樊市| 齐河县| 韶山市| 绵竹市| 吉安县| 绩溪县| 离岛区| 东阳市| 芜湖县| 藁城市| 崇左市| 抚远县| 镇康县| 洮南市| 名山县| 扶绥县| 策勒县| 泰宁县| 资兴市| 阿克陶县|