<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    和風細雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術自出。

    Socket基礎

    本文內容

    Socket概述
    Socket的重要API
    一個Socket通信的例子

    Socket是什么?

    Socket通常也稱作“套接字”,用于描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過“套接字”向網絡發(fā)出請求或者應答網絡請求。
    在java中,Socket和ServerSocket類庫位于java.net包中。ServerSocket用于服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。
    對于一個網絡連接來說,套接字是平等的,并沒有差別,不因為在服務器端或在客戶端而產生不同級別。

    Socket的直觀描述

    Socket的英文原義是“孔”或“插座”。在這里作為進程通信機制,取后一種意義。socket非常類似于電話插座。以一個國家級電話網為例。電話的通話雙方相當于相互通信的2個進程,區(qū)號是它的網絡地址;區(qū)內一個單位的交換機相當于一臺主機,主機分配給每個用戶的局內號碼相當于socket號。任何用戶在通話之前,首先要占有一部電話機,相當于申請一個socket;同時要知道對方的號碼,相當于對方有一個固定的socket。然后向對方撥號呼叫,相當于發(fā)出連接請求(假如對方不在同一區(qū)內,還要撥對方區(qū)號,相當于給出網絡地址)。對方假如在場并空閑(相當于通信的另一主機開機且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當于連接成功。雙方通話的過程,是一方向電話機發(fā)出信號和對方從電話機接收信號的過程,相當于向socket發(fā)送數據和從socket接收數據。通話結束后,一方掛起電話機相當于關閉socket,撤消連接。
    在電話系統(tǒng)中,一般用戶只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,話音傳輸的過程以及整個電話系統(tǒng)的技術細節(jié)對他都是透明的,這也與socket機制非常相似。socket利用網間網通信設施實現進程通信,但它對通信設施的細節(jié)毫不關心,只要通信設施能提供足夠的通信能力,它就滿足了。
     至此,我們對socket進行了直觀的描述。抽象出來,socket實質上提供了進程通信的端點。進程通信之前,雙方首先必須各自創(chuàng)建一個端點,否則是沒有辦法建立聯(lián)系并相互通信的。正如打電話之前,雙方必須各自擁有一臺電話機一樣。

    socket 是面向客戶/服務器模型而設計的

    socket 是面向客戶/服務器模型而設計的,針對客戶和服務器程序提供不同的socket 系統(tǒng)調用。客戶隨機申請一個socket (相當于一個想打電話的人可以在任何一臺入網電話上撥號呼叫),系統(tǒng)為之分配一個socket號;服務器擁有全局公認的 socket ,任何客戶都可以向它發(fā)出連接請求和信息請求(相當于一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。
    socket利用客戶/服務器模式巧妙地解決了進程之間建立通信連接的問題。服務器socket為全局所公認非常重要。讀者不妨考慮一下,兩個完全隨機的用戶進程之間如何建立通信?假如通信雙方沒有任何一方的socket 固定,就好比打電話的雙方彼此不知道對方的電話號碼,要通話是不可能的。

    Socket的應用

    Socket 接口是訪問 Internet 使用得最廣泛的方法。 如果你有一臺剛配好TCP/IP協(xié)議的主機,其IP地址是202.120.127.201, 此時在另一臺主機或同一臺主機上執(zhí)行ftp 202.120.127.201,顯然無法建立連接。因"202.120.127.201" 這臺主機沒有運行FTP服務軟件。同樣, 在另一臺或同一臺主機上運行瀏覽軟件 如Netscape,輸入"http://202.120.127.201",也無法建立連接。現在,如果在這臺主機上運行一個FTP服務軟件(該軟件將打開一個Socket, 并將其綁定到21端口),再在這臺主機上運行一個Web 服務軟件(該軟件將打開另一個Socket,并將其綁定到80端口)。這樣,在另一臺主機或同一臺主機上執(zhí)行ftp 202.120.127.201,FTP客戶軟件將通過21端口來呼叫主機上由FTP 服務軟件提供的Socket,與其建立連接并對話。而在netscape中輸入"http://202.120.127.201"時,將通過80端口來呼叫主機上由Web服務軟件提供的Socket,與其建 立連接并對話。 在Internet上有很多這樣的主機,這些主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,并綁定到一個端口上,不同的端口對應于不同的服務。Socket正如其英文原意那樣,象一個多孔插座。一臺主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節(jié)目。 客戶軟件將插頭插到不同編號的插座,就可以得到不同的服務。

    重要的Socket API

    accept方法用于產生“阻塞”,直到接受到一個連接,并且返回一個客戶端的Socket對象實例。“阻塞”是一個術語,它使程序運行暫時“停留”在這個地方,直到一個會話產生,然后程序繼續(xù);通常“阻塞”是由循環(huán)產生的。
    getInputStream方法獲得網絡連接輸入,同時返回一個IutputStream對象實例。
    getOutputStream方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例。 注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。

    一個Server-Client模型的程序的開發(fā)原理

    服務器,使用ServerSocket監(jiān)聽指定的端口,端口可以隨意指定(由于1024以下的端口通常屬于保留端口,在一些操作系統(tǒng)中不可以隨意使用,所以建議使用大于1024的端口),等待客戶連接請求,客戶連接后,會話產生;在完成會話后,關閉連接。
    客戶端,使用Socket對網絡上某一個服務器的某一個端口發(fā)出連接請求,一旦連接成功,打開會話;會話完成后,關閉Socket。客戶端不需要指定打開的端口,通常臨時的、動態(tài)的分配一個1024以上的端口。

    服務器端代碼

    public class ResponseThread implements Runnable {
      private static Logger logger = Logger.getLogger(ResponseThread.class);
     
      // 用于與客戶端通信的Socket
      private Socket incomingSocket;

      /**
       * 構造函數,用以將incomingSocket傳入
       * @param incomingSocket
       */
      public ResponseThread(Socket incomingSocket) {
        this.incomingSocket = incomingSocket;
      }

      public void run() {
        try {
          try {
            // 輸入流
            InputStream inStream = incomingSocket.getInputStream();
           
            // 輸出流
            OutputStream outStream = incomingSocket.getOutputStream();

            // 文本掃描器
            Scanner in = new Scanner(inStream);
           
            // 輸出流打印器
            PrintWriter out = new PrintWriter(outStream,true);
           
            while (in.hasNextLine()) {
              String line = in.nextLine();
              logger.info("從客戶端獲得文字:"+line);
             
              String responseLine=line+" 門朝大海 三河合水萬年流";
              out.println(responseLine);
              logger.info("向客戶端送出文字:"+responseLine);
            }
          } finally {
            incomingSocket.close();
          }
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
     public static void main(String[] args) {
        try {
          // 建立一個對2009端口進行監(jiān)聽的ServerSocket并開始監(jiān)聽
          ServerSocket socket=new ServerSocket(2009);
          logger.info("開始監(jiān)聽");
         
          while(true){
            // 產生阻塞,直到客戶端連接過來才會往下執(zhí)行
            logger.info("阻塞中,等待來自客戶端的連接請求");
            Socket incomingSocket=socket.accept();       
           
            // 執(zhí)行到這里客戶端已經連接過來了,incomingSocket就是創(chuàng)建出來和遠程客戶端Socket進行通信的Socket
            logger.info("獲得來自"+incomingSocket.getInetAddress()+"的請求."); 
           
            // 開辟一個線程,并把incomingSocket傳進去,在這個線程中服務器和客戶機開始通信
            ResponseThread responseThread=new ResponseThread(incomingSocket);
           
            // 啟動線程
            Thread thread=new Thread(responseThread);
            thread.start();
          }
         
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }

    客戶端代碼

    /**
     * Socket客戶端類
     * @author sitinspring
     *
     * @date 2008-2-26
     */
    public class SocketClient{
      private static Logger logger = Logger.getLogger(ResponseThread.class);
     
      public static void main(String[] args){
        try {
          // 建立一個Socket,試圖連接到位于127.0.0.1的主機的2009端口,如果服務器已經在監(jiān)聽則會接收到這個請求,accept方法產生一個和這邊通信的Socket
          Socket socket=new Socket("127.0.0.1",2009);
          logger.info("客戶端向服務器發(fā)起請求.");
         
          try {
            // 輸入流
            InputStream inStream = socket.getInputStream();
           
            // 輸出流
            OutputStream outStream = socket.getOutputStream();

            /**
             * 向服務器發(fā)送文字
             */
            // 輸出流打印器
            PrintWriter out = new PrintWriter(outStream);
            out.println("地震高崗 一派溪山千古秀");
            out.flush();
           
            /**
             * 接收服務器發(fā)送過來的文字
             */
            // 文本掃描器
            Scanner in = new Scanner(inStream);
            while (in.hasNextLine()) {
              String line = in.nextLine();
              logger.info("客戶端獲得響應文字="+ line);
            }
          } finally {
            // 關閉Socket
            socket.close();
          }
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }

    posted on 2008-02-26 13:53 和風細雨 閱讀(441) 評論(0)  編輯  收藏 所屬分類: J2SE

    主站蜘蛛池模板: 亚洲AⅤ优女AV综合久久久| 特级做A爰片毛片免费69| 亚洲А∨精品天堂在线| 亚洲人成网站色7799| 久久不见久久见免费影院| 亚洲一卡2卡4卡5卡6卡在线99| 在线a免费观看最新网站| 亚洲欧洲国产视频| 免费在线观看的网站| 亚洲人成人网站18禁| 国产在线ts人妖免费视频| 日本特黄特色AAA大片免费| 亚洲成aⅴ人片久青草影院| 一级毛片在线免费视频| 国产亚洲一区二区在线观看| 日本不卡免费新一区二区三区| 亚洲视频在线观看免费| 亚洲网站免费观看| 亚洲精品无码久久久久A片苍井空 亚洲精品无码久久久久YW | 亚洲色成人网站WWW永久| 国产情侣久久久久aⅴ免费 | 日本一区二区三区日本免费| 美女又黄又免费的视频| 国外亚洲成AV人片在线观看 | 成人毛片18女人毛片免费视频未| 亚洲av永久中文无码精品综合| 免费一级做a爰片久久毛片潮喷| 一级黄色片免费观看| 亚洲av无码一区二区乱子伦as| 国产h视频在线观看免费| 国产精品亚洲а∨无码播放不卡 | 免费看美女裸露无档网站| 亚洲码和欧洲码一码二码三码| 亚洲高清无码综合性爱视频| 中文字幕乱码系列免费| 亚洲导航深夜福利| 亚洲AV无码一区二三区| 中文字幕免费在线看线人| 午夜在线免费视频| 亚洲白色白色在线播放| 亚洲AV无码之日韩精品|