JavaSocket編程(三)

字號(hào):

服務(wù)器Sockets
    列表9.2是一個(gè)服務(wù)器應(yīng)用程序的一部分.
    列表9.2 一個(gè)簡(jiǎn)單的服務(wù)器程序
    /**
    * 一個(gè)監(jiān)聽端口并提供HTML文檔的程序.
    */
    class SimpleWebServer {
    public static void main(String args[])
    {
    ServerSocket serverSocket = null;
    Socket clientSocket = null;
    int connects = 0;
    try
    {
    {
    // 建立一個(gè)服務(wù)器socket
    serverSocket = new ServerSocket(80, 5);
    while (connects < 5)
    {
    // 等待連接
    clientSocket = serverSocket.accept();
    //服務(wù)連接
    ServiceClient(clientSocket);
    connects++;
    }
    serverSocket.close();
    }
    catch (IOException ioe)
    {
    System.out.println("Error in SimpleWebServer: " + ioe);
    }
    }
    public static void ServiceClient(Socket client)
    throws IOException
    {
    DataInputStream inbound = null;
    DataOutputStream outbound = null;
    try
    {
    // 得到IO流
    inbound = new DataInputStream( client.getInputStream());
    outbound = new DataOutputStream( client.getOutputStream());
    //格式化輸出(回應(yīng)頭和很少的HTML文檔)
    StringBuffer buffer = PrepareOutput();
    String inputLine;
    while ((inputLine = inbound.readLine()) != null)
    {
    //如果到了HTTP請(qǐng)求的尾部,就發(fā)送回應(yīng)
    if ( inputLine.equals("") )
    {
    outbound.writeBytes(buffer.toString());
    break;
    }
    }
    }
    finally
    {
    // 清除
    System.out.println("Cleaning up connection: " + client);
    tln("Cleaning up connection: " + client);
    outbound.close();
    inbound.close();
    client.close();
    client.close();
    }
    }
    服務(wù)器Sockets
    服務(wù)器并不是主動(dòng)地建立連接.相反地,他們是被動(dòng)地監(jiān)聽一個(gè)客戶端的連接請(qǐng)示然后給他們服務(wù).服務(wù)器是由類ServerSocket來建立的.下面的程序建立了一個(gè)服務(wù)器端socket 并把它綁定到80端口:
    ServerSocket serverSocket = new ServerSocket(80, 5);
    第一個(gè)參數(shù)是服務(wù)器要監(jiān)聽的端口.第二個(gè)參數(shù)是可選的.API文檔中說明了這是一個(gè)監(jiān)聽時(shí)間,但是在傳統(tǒng)的socket程序中第二個(gè)參數(shù)是監(jiān)聽深度.一個(gè)服務(wù)器可以同時(shí)接收多個(gè)連接請(qǐng)求,但是每次只能處理一個(gè).監(jiān)聽堆是一個(gè)無(wú)回答的連接請(qǐng)求隊(duì)列.上面的請(qǐng)求建立一個(gè)連接來處理最后五個(gè)請(qǐng)求.如果省略了后面的一個(gè)參數(shù),則默認(rèn)值是50.
    ServerSocket serverSocket = new ServerSocket(80, 5);
    一旦socket建立了并開始監(jiān)聽連接,進(jìn)來的連接將會(huì)建立并放在監(jiān)聽堆.accetp()方法把在堆中的連接取出來.
    Socket clientSocket = serverSocket.accept();
    這個(gè)方法返回一個(gè)用來與來訪者對(duì)話的客戶端連接.服務(wù)器本身不可能建立對(duì)話,相反地,服務(wù)器socket會(huì)使用accept()方法來產(chǎn)生一個(gè)新的socket.服務(wù)器socket依舊打開并排列新的連接請(qǐng)求.與客戶端socket一樣,下面的一步建立輸入和輸出流:
    DataInputStream inbound = new DataInputStream( clientSocket.getInputStream()
    ); DataOutputStream outbound = new DataOutputStream( clientSocket.getOutput
    Stream() );
    一般的I/O操作可以在新建的流中運(yùn)用.在服務(wù)器回應(yīng)前它等待客戶端發(fā)送一個(gè)空白的行.當(dāng)會(huì)話結(jié)束時(shí),服務(wù)器關(guān)閉流和客戶端socket.如果在隊(duì)列中沒有請(qǐng)示將會(huì)出現(xiàn)什么情況呢?那個(gè)方法將會(huì)等待一個(gè)的到來.這個(gè)行為叫阻塞.accept()方法將會(huì)阻塞服務(wù)器線程直到一個(gè)呼叫到來.當(dāng)5個(gè)連接處理完閉之后,服務(wù)器退出.任何的在隊(duì)列中的呼叫將會(huì)被取消.
    所有的服務(wù)器都要有以下的基本的步驟:
    1.建立一個(gè)服務(wù)器socket并開始監(jiān)聽.
    2.使用accept()方法取得新的連接.
    3.建立輸入和輸出流.
    4.在已有的協(xié)議上產(chǎn)生會(huì)話.
    5.關(guān)閉客戶端流和socket.
    6.回到第二步或者到第七步.
    7.關(guān)閉服務(wù)器socket.