熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java中的Socket編程

2022-06-13   來源: Java核心技術 

  Socket是網絡上運行的兩個程序間雙向通訊的一端它既可以接受請求也可以發送請求利用它可以較為方便的編寫網絡上數據的傳遞在Java中有專門的Socket類來處理用戶的請求和響應利用Socket類的方法就可以實現兩台計算機之間的通訊這裡就介紹一下在Java中如何利用Socket進行網絡編程
  
    在Java中Socket可以理解為客戶端或者服務器端的一個特殊的對象這個對象有兩個關鍵的方法一個是getInputStream方法另一個是getOutputStream方法getInputStream方法可以得到一個輸入流客戶端的Socket對象上的getInputStream方法得到的輸入流其實就是從服務器端發回的數據流GetOutputStream方法得到一個輸出流客戶端Socket對象上的getOutputStream方法返回的輸出流就是將要發送到服務器端的數據流(其實是一個緩沖區暫時存儲將要發送過去的數據)
  
    程序可以對這些數據流根據需要進行進一步的封裝本文的例子就對這些數據流進行了一定的封裝(關於封裝可以參考Java中流的實現部分)
  
    為了更好的說明問題這裡舉了一個網上對話的例子客戶端啟動以後服務器會啟動一個線程來與客戶進行文字交流
  
    要完成這個工作需要完成三個部分的工作以下依次說明
  
    一建立服務器類
  
    Java中有一個專門用來建立Socket服務器的類名叫ServerSocket可以用服務器需要使用的端口號作為參數來創建服務器對象
  
  ServerSocket server = new ServerSocket()
  
    這條語句創建了一個服務器對象這個服務器使用號端口當一個客戶端程序建立一個Socket連接所連接的端口號為服務器對象server便響應這個連接並且serveraccept()方法會創建一個Socket對象服務器端便可以利用這個Socket對象與客戶進行通訊
  
  Socket incoming = serveraccept()
  
    進而得到輸入流和輸出流並進行封裝
  
  BufferedReader in = new BufferedReader(new
        InputStreamReader(incominggetInputStream()));
  PrintWriter out = new PrintWriter(incominggetOutputStream()true);
  
    隨後就可以使用inreadLine()方法得到客戶端的輸入也可以使用outprintln()方法向客戶端發送數據從而可以根據程序的需要對客戶端的不同請求進行回應
  
    在所有通訊結束以後應該關閉這兩個數據流關閉的順序是先關閉輸出流再關閉輸入流即使用
  
  outclose();
  inclose();
  
  二建立客戶端代碼
  
    相比服務器端客戶端要簡單一些客戶端只需用服務器所在機器的ip以及服務器的端口作為參數創建一個Socket對象得到這個對象後就可以用建立服務器部分介紹的方法實現數據的輸入和輸出
  
  Socket socket = new Socket();
  in = new BufferedReader(new InputStreamReader(socketgetInputStream()));
  out = new PrintWriter(socketgetOutputStream()true);
  
    以上的程序代碼建立了一個Socket對象這個對象連接到ip地址為的主機上端口為的服務器對象並且建立了輸入流和輸出流分別對應服務器的輸出和客戶端的寫入
  
    三建立用戶界面
  
    讀者可以根據自己的喜好建立自己的用戶界面這不是本文的重點
  
    經過以上三個步驟就可以建立一個比較簡單的對話程序但是為了使這個程序更加完善應進行以下幾個改進
  
    一現在服務器只能服務一個客戶也就是單線程的可以將它改進為多線程服務器
  
  try
  { file://建立服務器
   ServerSocket server = new ServerSocket();
   int i=;
   for(;;)
   {
    Socket incoming = serveraccept();
    new ServerThread(incomingi)start();
    i++;
   }
  }catch (IOException ex){ exprintStackTrace(); }
  
    循環檢測是否有客戶連接到服務器上如果有則創建一個線程來服務這個客戶這個線程的名稱是ServerThread這個類擴展了Thread類它的編寫方法與前述的服務器的寫法相同
  
    二為了可以隨時得到對方傳送過來的消息可以在服務器以及客戶端各建立一個獨立的線程來察看輸入流如果輸入流中有輸入則可以即時顯示出來代碼如下
  
  new Thread()
  {
   public void run()
   {
    try
    { 
     while(true)
     {
      checkInput();
      sleep();//每毫秒檢測一次
     }
    }catch (InterruptedException ex)
   {
   }catch(IOException ex)
   {
    }
   }
  }start();
  
  其中的checkInput()方法為
  private void checkInput() throws IOException
  {
   String line;
   if((line=inreadLine())!=null) file://檢測輸入流中是否有新的數據
    tsetPartner(line); file://將數據流中的消息顯示出來
  }
  
    通過以上改進程序就可以比較好的運行了
  
  附服務器的實現代碼
  
  import *;
  import javaio*;
  import javaawteventActionEvent;
  import javaawteventActionListener;
  
  public class talkServer
  { public static void main(String[] args)
   { try
    { file://建立服務器
     ServerSocket server = new ServerSocket();
     int i=;
     for(;;)
      { Socket incoming = serveraccept();
       new ServerThread(incomingi)start();
       i++;
      }
     }catch (IOException ex){
     exprintStackTrace();
    }
   }
  }
  
  class ServerThread extends Thread implements ActionListener
  {
   private int threadNum;
   private Socket socket;
   talkServerFrm t;
   BufferedReader in;
   PrintWriter out;
   private boolean talking=true;
   public ServerThread(Socket sint c)
   { threadNum = c;
    socket = s;
   }
  
  public void actionPerformed(ActionEvent e)
  { Object source = egetSource();
   try{
    if(source==tbtnSend)
     { outprintln(tgetTalk());
      tclearTalk();
    }else
    if(source==tbtnEnd)
     { outprintln(談話過程被對方終止);
      outclose();
      inclose();
      talking = false;
     }
   }catch(IOException ex){
   }
  }
  
  public void run()
  { try{
    t=new talkServerFrm(new Integer(threadNum)toString()this);
    tsetSize();
    tshow();
    in = new BufferedReader(new
        InputStreamReader(socketgetInputStream()));
    out = new PrintWriter(socketgetOutputStream()true);
  }catch(Exception e){
  }
   new Thread()
   { public void run()
    { try{
      while(true)
      { checkInput();
       sleep();
    }
   }catch (InterruptedException ex){
   }catch(IOException ex){
   }
   }
   }start();
   while(talking)
   { }
   tdispose();
   }
  
  private void checkInput() throws IOException
  { String line;
   if((line=inreadLine())!=null)
    tsetPartner(line); file://這是界面類裡的方法
    file://用來將line的內容輸出到用戶界面
   }
  }
  

From:http://tw.wingwit.com/Article/program/Java/hx/201311/26984.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.