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

比爾學Java:Java Socket篇

2013-11-23 19:35:39  來源: Java核心技術 

  比爾最近接到一個項目是要在原來的系統上實現客戶端與服務器的連接原來的系統是用Java開發的項目組討後決定應用Java提供的Socket類來解決問題比爾是C開發的高手對Java卻只略知皮毛所以比爾一頭扎進Java中開始他的學習歷程當然首先還要解決眼前的問題學習Socket編程
  在學習Socket編程之前先看看自己是否熟悉TCPUDPPorts等網絡基本概念要是還不熟悉的話就得先去補補課羅!
  Socket 的基本概念
  Socket也就是俗稱的套接字
  Sun Java中的定義是運行在網絡上的兩個程序間雙向通訊連接的末端它提供客戶端和服務器端的連接通道Socket綁定於特定端口這樣TCP層就知道將數據提供給哪個應用程序
  字面上的理解Socket的意思是插座你還可以把它形象地理解為打電話用的電話機你從聽筒裡聽到對方聲音同時將聲音通過話筒傳給對方
  
  我想你現在和我剛開始的時候一樣好像有點明白又好像不是很明白沒關系我希望通過下面例子的講解你能夠徹底地掌握它在實例之前讓我們先來看看Socket實現的基本原理
  Socket編程實現原理
  從連接的建立到連接的結束每個Socket應用都大致包含以下幾個基本步驟
  服務器端socket綁定於特定端口服務器偵聽socket等待連接請求
  客戶端向服務器和特定端口提交連接請求
  服務器接受連接產生一新的socket綁定到另一端口由此socket來處理和客戶端的交互服務器繼續偵聽原socket來接受其他客戶端的連接請求
  
  連接成功後客戶端也產生一socket並通過它來與服務器端通訊(注意客戶端socket並不與特定端口綁定)
  接下來服務器端和客戶端就通過讀取和寫入各自的socket來進行通訊
  注意本文中只講解基於TCP的Socket應用
  Java中的Socket類
  Java中提供兩個類(在包中)——Socket和ServerSocket來分別實現客戶端和服務器端Socket但Socket的實際工作是由抽象類SocketImpl的實例來完成的這其實是設計模式中Abstract Factory模式的一個應用
  
  ServerSocket類的常用構造器和主要方法
  
  ServerSocket(int port) 在指定的端口號上產生一服務器端socket
  Socket accept()
  偵聽socket接受連接
  Socket類的常見構造器和主要方法
  
  Socket(String host int port) 生成一socket並連接至指定的主機和端口
  InputStream getInputStream() 返回socket的輸入流
  OutputStream getOuputStream() 返回socket的輸出流
  一個客戶服務器實例
  了解了上面的一些基本知識以後我想大家現在都迫不及待地想親自動手編寫自己的socket那就讓我們開始吧!在這個例子中我們模仿了一個Echo服務它偵聽端口客戶端接受用戶鍵盤輸入並向服務器端發出連接請求服務器端接受客戶端連接連接成功後建立會話客戶端於是向服務器端發送用戶輸入信息服務器端接收此信息並且簡單返回給客戶端源碼如下
  
  (服務器端)
  
  /**
   * <p>Title:EchoServerjava </p>
   * <p>Description: EchoServer create a echolike server at port </p>
   * @author Mac
   * @version //
   */
  
  import *;
  import javaio*;
  
  public class EchoServer
  {
   public static void main (String[] args) throws IOException
   {
   ServerSocket echoServer = null;
   try
   {
   echoServer = new ServerSocket(); //creat a server socket at port
  (問題一)
   }
   catch(IOException e)
   {
   Systemerrprintln("Couldnt listen on port:");
   Systemexit();
   }
  
   Socket echoClient = null;
   try
   {
   echoClient = echoServeraccept(); //accept a connection
   }
   catch(IOException e)
   {
   Systemerrprintln("IO error:" + egetMessage());
   Systemexit();
   }
  
   PrintWriter out = new PrintWriter(echoClientgetOutputStream()true);
   //gets the sockets output stream and opens a PrintWriter on it
   //if you remove the argument truewhat will happen?(問題三)
   BufferedReader in = new BufferedReader(
   new InputStreamReader(echoClientgetInputStream()));
   //gets the sockets input stream and opens a BufferedReader on it
   String strFromClient;
  
   while((strFromClient = inreadLine()) != null)
   {
   outprintln("result is :" + strFromClient);
   }
  
   inclose();
   outclose();
   echoClientclose();
   echoServerclose();
   }
  }
  
  (客戶端)
  /**
   *<p>Title:EchoClientjava </p>
   *<p>Description: EchoClient creates a socket thereby getting a connection to
  echolike server</p>
   * @author Mac Wang
   * @version //
   */
  
  import *;
  import javaio*;
  
  public class EchoClient
  {
  
   public static void main(String[] args)
   {
   try
   {
  Socket echoClient = new Socket("yourhostname");
  //creat a new socket connected to host and port
   PrintWriter out = new PrintWriter(echoClientgetOutputStream()true);
  
   BufferedReader in = new BufferedReader(
   new InputStreamReader(echoClientgetInputStream()));
   String fromServerfromUser;
   BufferedReader stdIn = new BufferedReader(
   new InputStreamReader(Systemin));
   //gets the system input stream and opens a BufferedReader on it
   while ((fromUser = stdInreadLine()) != null)
   {
   if (fromUserequals("bye")) break;
  //when user types "bye" then end
  
   Systemoutprintln("input is:" + fromUser);
   outprintln(fromUser);
  
   fromServer = inreadLine();
   Systemoutprintln(fromServer);
   }
   outclose();
   inclose();
   echoClientclose();
   }
   catch(UnknownHostException e)
   {
   Systemerrprintln("Unknown host:yourhostname");
   Systemexit();
   }
   catch(IOException e)
   {
   Systemerrprintln("I/ error:" + egetMessage());
   Systemexit();
   }
   }
  }
  現在大家可以分別運行Server和Client看看程序運行效果(注意你必須將yourhostname替換成你自己的主機名或IP地址)並且思考以下幾個問題
  
  把端口號換成後看看程序運行效果?那麼呢?是不是任何數字都可以呢?
  
  如果不采用我們自己編寫的echo server而是連接到系統本身提供的echo server(端口號為試試看會發生什麼情況客戶端Socket是否需要改變呢?
  
  去掉PrintWriter中的參數True看看程序運行的效果?
  
  注意程序中是如何讀取和寫入Socket的?
  試著多打開幾個客戶端看看效果如何?
  從問題中大家可以看出來上面的例子只支持一個用戶連接那麼如何支持多用戶的同時訪問呢?最簡單有效的方法就是利用多線程實現每個線程對應一個用戶連接server接受一個client連接後就新產生一個線程並交由它去處理余下的工作下面就是支持多用戶的服務器端實現
  /**
  *<p>Title:EchoMultiServer </p>
   *<p>Description: EchoServer create a echolike server at port which supports
  multiclient</p>
   * @author Mac Wang
   * @version //
   */
  import *;
  import javaio*;
  class EchoMultiServerThread extends Thread
  {
   private Socket echoClient = nul
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27141.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.