posts - 310, comments - 6939, trackbacks - 0, articles - 3
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          多線程Java Socket編程示例

          Posted on 2007-10-15 12:37 詩(shī)特林 閱讀(92559) 評(píng)論(25)  編輯  收藏 所屬分類: Socket
                                                           多線程Java Socket編程示例

          這篇做為學(xué)習(xí)孫衛(wèi)琴<<Java網(wǎng)絡(luò)編程精解>>的學(xué)習(xí)筆記吧.其中采用Java 5的ExecutorService來(lái)進(jìn)行線程池的方式實(shí)現(xiàn)多線程,模擬客戶端多用戶向同一服務(wù)器端發(fā)送請(qǐng)求.

          1.服務(wù)端
          package sterning;

          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.io.OutputStream;
          import java.io.PrintWriter;
          import java.net.*;
          import java.util.concurrent.*;

          public class MultiThreadServer {
              
          private int port=8821;
              
          private ServerSocket serverSocket;
              
          private ExecutorService executorService;//線程池
              private final int POOL_SIZE=10;//單個(gè)CPU線程池大小
              
              
          public MultiThreadServer() throws IOException{
                  serverSocket
          =new ServerSocket(port);
                  
          //Runtime的availableProcessor()方法返回當(dāng)前系統(tǒng)的CPU數(shù)目.
                  executorService=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);
                  System.out.println(
          "服務(wù)器啟動(dòng)");
              }

              
              
          public void service(){
                  
          while(true){
                      Socket socket
          =null;
                      
          try {
                          
          //接收客戶連接,只要客戶進(jìn)行了連接,就會(huì)觸發(fā)accept();從而建立連接
                          socket=serverSocket.accept();
                          executorService.execute(
          new Handler(socket));
                          
                      }
           catch (Exception e) {
                          e.printStackTrace();
                      }

                  }

              }

              
              
          public static void main(String[] args) throws IOException {
                  
          new MultiThreadServer().service();
              }


          }


          class Handler implements Runnable{
              
          private Socket socket;
              
          public Handler(Socket socket){
                  
          this.socket=socket;
              }

              
          private PrintWriter getWriter(Socket socket) throws IOException{
                  OutputStream socketOut
          =socket.getOutputStream();
                  
          return new PrintWriter(socketOut,true);
              }

              
          private BufferedReader getReader(Socket socket) throws IOException{
                  InputStream socketIn
          =socket.getInputStream();
                  
          return new BufferedReader(new InputStreamReader(socketIn));
              }

              
          public String echo(String msg){
                  
          return "echo:"+msg;
              }

              
          public void run(){
                  
          try {
                      System.out.println(
          "New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
                      BufferedReader br
          =getReader(socket);
                      PrintWriter pw
          =getWriter(socket);
                      String msg
          =null;
                      
          while((msg=br.readLine())!=null){
                          System.out.println(msg);
                          pw.println(echo(msg));
                          
          if(msg.equals("bye"))
                              
          break;
                      }

                  }
           catch (IOException e) {
                      e.printStackTrace();
                  }
          finally{
                      
          try {
                          
          if(socket!=null)
                              socket.close();
                      }
           catch (IOException e) {
                          e.printStackTrace();
                      }

                  }

              }

          }

          2.客戶端
          package sterning;

          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStreamReader;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;

          public class MultiThreadClient {
              
              
          public static void main(String[] args) {
                  
          int numTasks = 10;
                  
                  ExecutorService exec 
          = Executors.newCachedThreadPool();

                  
          for (int i = 0; i < numTasks; i++{
                      exec.execute(createTask(i));
                  }


              }


              
          // 定義一個(gè)簡(jiǎn)單的任務(wù)
              private static Runnable createTask(final int taskID) {
                  
          return new Runnable() {
                      
          private Socket socket = null;
                      
          private int port=8821;

                      
          public void run() {
                          System.out.println(
          "Task " + taskID + ":start");
                          
          try {                    
                              socket 
          = new Socket("localhost", port);
                              
          // 發(fā)送關(guān)閉命令
                              OutputStream socketOut = socket.getOutputStream();
                              socketOut.write(
          "shutdown\r\n".getBytes());

                              
          // 接收服務(wù)器的反饋
                              BufferedReader br = new BufferedReader(
                                      
          new InputStreamReader(socket.getInputStream()));
                              String msg 
          = null;
                              
          while ((msg = br.readLine()) != null)
                                  System.out.println(msg);
                          }
           catch (IOException e) {                    
                              e.printStackTrace();
                          }

                      }


                  }
          ;
              }

          }


          從而實(shí)現(xiàn)了多個(gè)客戶端向服務(wù)器端發(fā)送請(qǐng)求,服務(wù)器端采用多線程的方式來(lái)處理的情況.再結(jié)合我之前的例子---Java基于Socket文件傳輸示例,就可以實(shí)現(xiàn)多線程文件的傳輸了

          評(píng)論

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2007-11-10 14:25 by xiongzeng
          請(qǐng)問作者:
          可不可以利用服務(wù)端主動(dòng)發(fā)信?

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2007-12-07 13:12 by qifen
          膏藥帖~~

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2008-01-07 22:19 by java綜合網(wǎng)
          很好!不錯(cuò)!

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2008-03-14 11:36 by fgfdg
          dgdfggfdgdf

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2008-05-28 17:14 by 鐘僥
          我也是參照孫的書,可是運(yùn)行不能得到正確的結(jié)果!很是郁悶啊
          [code]
          package com.zz.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 EchoServer {

          private int port = 8000;
          private ServerSocket ss;

          public EchoServer() throws IOException {
          ss = new ServerSocket(port);
          System.out.println("server is starting....");
          }

          private String echoString(String msg){
          return "echo:" + msg;
          }
          public static void main(String[] args) {
          try {
          new EchoServer().service();
          } catch (IOException e) {
          e.printStackTrace();
          }
          }

          private void service(){
          while(true){
          Socket s = null;
          try{
          s = ss.accept();
          System.out.println("a client is coming......");
          BufferedReader br = this.getReader(s);
          PrintWriter pw = this.getWriter(s);
          String msg = null;
          while((msg = br.readLine()) != null){
          System.out.println(msg);
          pw.println(this.echoString(msg)+"\n");
          pw.flush();
          if(msg.equals("bye")) break;
          }
          }catch(IOException e ){

          }
          }
          }

          private PrintWriter getWriter(Socket s) throws IOException {
          return new PrintWriter(s.getOutputStream());
          }

          private BufferedReader getReader(Socket s) throws IOException {
          return new BufferedReader(new InputStreamReader(s.getInputStream()));
          }

          }



          [/code]

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2008-05-28 17:15 by 鐘僥
          package com.zz.socket;

          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStreamReader;
          import java.io.PrintWriter;
          import java.net.Socket;

          public class EchoClient {
          private String host = "localhost";
          private int port = 8000;
          private Socket socket;

          private EchoClient() throws IOException {
          socket = new Socket(host, port);
          }

          public void talk() throws IOException {
          try {
          BufferedReader br = getReader(socket);
          PrintWriter pw = getWriter(socket);
          BufferedReader localReader = new BufferedReader(
          new InputStreamReader(System.in));
          String msg = null;
          while ((msg = localReader.readLine())!= null) {
          pw.println(msg+"\n");
          pw.flush();
          System.out.println(br.readLine());
          if (msg.equals("bye"))
          break;
          }
          } catch (IOException e) {
          } finally {
          try {
          socket.close();
          } catch (IOException e) {
          e.printStackTrace();
          }
          }
          }

          private PrintWriter getWriter(Socket s) throws IOException {
          return new PrintWriter(s.getOutputStream());
          }

          private BufferedReader getReader(Socket s) throws IOException {
          return new BufferedReader(new InputStreamReader(s.getInputStream()));
          }

          /**
          * @param args
          * @throws IOException
          */
          public static void main(String[] args) throws IOException {
          new EchoClient().talk();

          }

          }

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2008-06-16 23:04 by 有貓相伴的日子
          這個(gè)代碼有很多問題,如請(qǐng)求處理,怎么封裝請(qǐng)求對(duì)象,把請(qǐng)求對(duì)象放一隊(duì)列

          從服務(wù)器端怎么發(fā)消息到客戶端.....

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2009-04-27 10:22 by fei
          貌似整體思想可以,但是,程序的問題就比較多了...

          # re: 多線程Java Socket編程示例[未登錄]  回復(fù)  更多評(píng)論   

          2009-05-07 15:38 by jh
          第三方殺毒

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2009-05-07 17:14 by OverKill
          如果多個(gè)線程對(duì)同一資源進(jìn)行讀取,能保證資源的原子性嗎?應(yīng)該對(duì)資源加鎖

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2009-05-17 15:52 by 點(diǎn)水點(diǎn)點(diǎn)
          正找這樣的文章 多謝

          # re: 多線程Java Socket編程示例[未登錄]  回復(fù)  更多評(píng)論   

          2009-08-23 19:12 by Mark
          如何設(shè)定超時(shí)的問題呢?

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2010-05-09 13:48 by 詩(shī)特林fans
          我是java網(wǎng)絡(luò)編程的初學(xué)者很想加 詩(shī)特林 為好友向你請(qǐng)教些問題。我的qq826463574

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2010-05-09 14:05 by 詩(shī)特林fans
          服務(wù)器端:
          public class MultiThreadServer {
          private int port=8821;
          private ServerSocket serverSocket;
          private ExecutorService executorService;//線程池
          private final int POOL_SIZE=10;//單個(gè)CPU線程池大小

          public MultiThreadServer() throws IOException{
          serverSocket=new ServerSocket(port);
          //Runtime的availableProcessor()方法返回當(dāng)前系統(tǒng)的CPU數(shù)目.
          executorService=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);
          System.out.println("服務(wù)器啟動(dòng)");
          }

          public void service(){
          while(true){
          Socket socket=null;
          try {
          //接收客戶連接,只要客戶進(jìn)行了連接,就會(huì)觸發(fā)accept();從而建立連接
          socket=serverSocket.accept();
          executorService.execute(new Handler(socket));

          } catch (Exception e) {
          e.printStackTrace();
          }
          }
          }

          public static void main(String[] args) throws IOException {
          new MultiThreadServer().service();
          }

          }

          class Handler implements Runnable{
          private Socket socket;
          public Handler(Socket socket){
          this.socket=socket;
          }
          /*private DataOutputStream dos(Socket socket) throws IOException{
          OutputStream socketOut=socket.getOutputStream();
          return new DataOutputStream(socketOut);
          }
          private DataInputStream dis(Socket socket) throws IOException{
          InputStream socketIn=socket.getInputStream();
          return new DataInputStream(socketIn);
          }*/

          public void run(){
          try {
          System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
          OutputStream os = socket.getOutputStream();
          DataOutputStream dos = new DataOutputStream(os);

          InputStream is = socket.getInputStream( );
          DataInputStream dis=new DataInputStream(is);
          new myserverread(dis).start();
          new myserverwite(dos).start();


          } catch (IOException e) {
          e.printStackTrace();
          }/*finally{
          try {
          if(socket!=null)
          socket.close();
          } catch (IOException e) {
          e.printStackTrace();
          }
          }*/
          }
          }
          class myserverread extends Thread{
          private DataInputStream dis;
          public myserverread (DataInputStream dis){
          this.dis=dis;
          }
          public void run(){
          String info;
          try{
          while(true)
          {
          info=dis.readUTF();
          System.out.println("對(duì)方說(shuō)"+info);
          if (info.equals("bye")){
          System.out.println("對(duì)方下線,程序退出");
          System.exit(0);}
          }
          }
          catch (Exception e){e.getStackTrace();}

          }
          }

          class myserverwite extends Thread{
          private DataOutputStream dos;
          public myserverwite (DataOutputStream dos){
          this.dos=dos;
          }
          public void run(){
          BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
          String info;
          try{
          while(true)
          {
          info=br.readLine();
          dos.writeUTF(info);
          if (info.equals("bye")){
          System.out.println("自己下線,程序退出");
          System.exit(0);}
          }
          }
          catch (Exception e){e.getStackTrace();}

          }
          }



          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2010-05-09 14:06 by 詩(shī)特林fans
          客戶端:


          import java.io.BufferedReader;
          import java.io.DataInputStream;
          import java.io.DataOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;



          public class MultiThreadClient {

          public static void main(String[] args) {
          int ID=Info.i;

          ExecutorService exec = Executors.newCachedThreadPool();

          /* for (int i = 0; i < numTasks; i++) {
          exec.execute(createTask(i));
          }
          */
          System.out.println("客戶端線程"+ID+"已啟動(dòng)~~");
          exec.execute(createTask(ID));
          Info.i=ID++;

          }

          // 定義一個(gè)簡(jiǎn)單的任務(wù)
          private static Runnable createTask(int taskID) {
          // this.taskID=taskID;
          return new Runnable() {
          private Socket socket = null;
          private int port=8821;

          public void run() {

          // System.out.println("Task " + taskID + ":start");
          try {
          socket = new Socket("localhost", port);
          // 發(fā)送關(guān)閉命令
          InputStream is = socket.getInputStream( );
          DataInputStream dis=new DataInputStream(is);

          OutputStream os = socket.getOutputStream();
          DataOutputStream dos = new DataOutputStream(os);

          new myclientread(dis).start();
          new myclientwite(dos).start();

          } catch (IOException e) {
          e.printStackTrace();
          }
          }

          };
          }
          }
          class myclientread extends Thread{
          private DataInputStream dis;
          public myclientread (DataInputStream dis){
          this.dis=dis;
          }
          public void run(){
          String info;
          try{
          while(true)
          {
          info=dis.readUTF();
          System.out.println("對(duì)方說(shuō)"+info);
          if (info.equals("bye")){
          System.out.println("對(duì)方下線,程序退出");
          System.exit(0);}
          }
          }
          catch (Exception e){e.getStackTrace();}

          }
          }

          class myclientwite extends Thread{
          private DataOutputStream dos;
          public myclientwite (DataOutputStream dos){
          this.dos=dos;
          }
          public void run(){
          BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
          String info;
          try{
          while(true)
          {
          info=br.readLine();
          dos.writeUTF(info);
          if (info.equals("bye")){
          System.out.println("自己下線,程序退出");
          System.exit(0);}
          }
          }
          catch (Exception e){}

          }
          }

          這個(gè)程序我想實(shí)現(xiàn)多用戶與服務(wù)器的連接交互問題,但是能過連接上但是不能實(shí)現(xiàn)交互,這是為什么呢?我是java網(wǎng)絡(luò)編程初學(xué)者謝謝您的指教急待您的回復(fù)!

          # re: 多線程Java Socket編程示例[未登錄]  回復(fù)  更多評(píng)論   

          2010-08-19 16:52 by zheng
          學(xué)習(xí)了

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2012-04-01 16:54 by 安安
          你好,這樣不會(huì)出現(xiàn)中文亂碼嗎?

          # re: 多線程Java Socket編程示例[未登錄]  回復(fù)  更多評(píng)論   

          2013-06-03 20:55 by 孫杰
          求 超市收銀系統(tǒng) 用XML Socket 和多線程 做的 有的發(fā)我郵箱 769566815@qq.com

          # re: 多線程Java Socket編程示例[未登錄]  回復(fù)  更多評(píng)論   

          2013-06-03 20:58 by 孫杰
          跪求 急用 6月5號(hào)交上去

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2014-04-30 10:37 by 126
          @鐘僥
          while(true){
          Socket s = null;

          每次s都是null

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2014-04-30 10:42 by 126
          看錯(cuò)了,

          s = ss.accept();

          你那個(gè)代碼變量名太差了吧!看都看不清!

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2014-05-22 16:29 by momo128
          請(qǐng)問您知不知道哪里有socket的學(xué)習(xí)視頻啊?因?yàn)槭诸^資料實(shí)在有限,有好多不懂的地方。如果有的話請(qǐng)發(fā)到我的郵箱960696649@qq.com,麻煩您了~

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2014-07-30 22:02 by 月小升
          很不錯(cuò)的socket教程

          # re: 多線程Java Socket編程示例  回復(fù)  更多評(píng)論   

          2014-11-18 16:42 by 一個(gè)好人
          @有貓相伴的日子
          項(xiàng)目中正打算使用這段代碼的,看你的品論才發(fā)現(xiàn) 確實(shí)沒有用到隊(duì)列,如果并發(fā)數(shù)量超過線程數(shù)會(huì)出現(xiàn)什么情況?
          主站蜘蛛池模板: 轮台县| 濮阳县| 梅河口市| 巨野县| 界首市| 平湖市| 乐安县| 松阳县| 葫芦岛市| 朝阳市| 吉木萨尔县| 喀什市| 安陆市| 鱼台县| 瑞金市| 叶城县| 清新县| 呼图壁县| 武宣县| 林西县| 鹤峰县| 游戏| 章丘市| 灵台县| 馆陶县| 松阳县| 灵川县| 遂溪县| 甘洛县| 亚东县| 会理县| 雅江县| 尼木县| 青铜峡市| 麦盖提县| 佳木斯市| 德安县| 敖汉旗| 大理市| 缙云县| 尚义县|