隨筆 -- IO -- Socket/ServerSocket -- Echo(BIO)實例

隨筆 -- IO -- Socket/ServerSocket -- 系統概述html

Java中提供的專門的網絡開發程序包------java.netjava

Java的網絡編程提供的兩種通訊協議:TCP和UDP編程

    19.1 IP與InetAddress服務器

      19.1.1 IP地址簡介網絡

      19.1.2 InetAddress多線程

        InetAddress類主要表示IP地址,這個類有兩個子類:Inet4Address、Inet6Address。app

        InetAddress類的經常使用方法:socket

        ⊙ public static InetAddress getByName(String host)throws UnknownHostException :經過主機名稱獲得InetAddress對象post

        ⊙ public static InetAddress getLocalHost() throws UnknownHostException : 經過本機獲得InetAddress對象this

        ⊙ public String getHostName() : 獲得IP地址

        ⊙ public boolean isReachable(int timeout)throws IOException : 判斷地址是否能夠到達,同時指定超時時間。

package java_.net_.demo.java_15_5;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressMain {

    public static void main(String[] args) throws Exception {

        InetAddress locAdd = null;
        InetAddress remAdd = null;
        locAdd = InetAddress.getLocalHost();
        remAdd = InetAddress.getByName("www.baidu.com");
        System.out.println("本機名稱 :" + locAdd.getHostName());
        System.out.println("本機IP地址 :" + locAdd.getHostAddress());
        System.out.println("百度IP地址 :" + remAdd);
        System.out.println("本機是否可達 :" + locAdd.isReachable(5000));
        System.out.println("百度是否可達 :" + remAdd.isReachable(5000));
    }
}

    19.2 URL與URLConnection

      19.2.1 URL

        URL統一資源定位符,能夠直接使用此類找到互聯網上的資源(如一個簡單的網頁)。

        URL類的經常使用方法:

        ⊙ public URL(String spec) throws MalformedURLException : 根據指定的地址實例化URL對象。

        ⊙ public URL(String protocal,String host,int port,String file) throws MalformedURLException : 實例化URL對象,並指定協議、主機、端口名稱、資源文件。

        ⊙ public URLConnection openConnection() throws IOException : 取得一個URLConnection對象。

        ⊙ public final InputStream openStream() throws IOException : 取得輸入流。

package java_.net_.demo.java_15_5.URL_;

import java.io.InputStream;
import java.net.URL;
import java.util.Scanner;

public class URLMain {

    public static void main(String[] args) throws Exception{
        
        URL url = new URL("http","www.mldnjava.cn",80,"/curriculum.htm");
        InputStream input = url.openStream();
        Scanner sc = new Scanner(input);
        sc.useDelimiter("\n");
        while(sc.hasNext()){
            System.out.println(sc.next());
        }
    }
}

      19.2.2 URLConnection

        URLConnection是封裝訪問遠程網絡資源通常方法的類,經過它能夠創建與遠程服務器的鏈接,檢查遠程資源的一些屬性。

        此類的經常使用方法:

        ⊙ public int getContentLength() : 取得內容的長度。

        ⊙ public String getContentType() : 取得內容的類型。

        ⊙ public InputStream getInputStream() throws IOException : 取得鏈接的輸入流。

        URLConnection對象能夠經過URL實例的openConnection()方法取得。

package java_.net_.demo.java_15_5.URLConnection;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;

public class URLConnectionMain {

    public static void main(String[] args) throws Exception{
        
        URL url = new URL("http://www.mldnjava.cn");
        URLConnection urlCon = url.openConnection();
        System.out.println("內容大小 :" + urlCon.getContentLength());
        System.out.println("內容類型 :" + urlCon.getContentType());
        InputStream input = urlCon.getInputStream();
        Scanner sc = new Scanner(input);
        sc.useDelimiter("\n");
        while (sc.hasNext()) {
            System.out.println(sc.next());
        }
    }
}

    19.3 URLEncoder 與 URLDecoder

      在Java中若是要完成編碼和解碼操做就必須使用URLEncoder 和 URLDecoder兩個類。

      URLEncoder 能夠爲傳遞的內容進行編碼;URLDecoder能夠爲傳遞的內容進行解碼。

      URLEncoder類經常使用的方法:

      ⊙ public static Spring encode(String s,String enc) throws UnsupportedEncodingException : 使用指定的編碼機制將字符串轉換爲application/x-www-form-urlencoded格式。

      URLDecoder類的經常使用方法:

      ⊙ public static Spring decode(String s,String enc) throws UnsupportedEncodingException : 使用指定的編碼機制對application/x-www-form-urlencoded字符串解碼。

package java_.net_.demo.java_15_5.URLEncoder;

import java.net.URLDecoder;
import java.net.URLEncoder;

public class URLEncoderMain {

    public static void main(String[] args) throws Exception{
        
        String keyWord = "lime甲骨文";
        String encod = URLEncoder.encode(keyWord, "UTF-8");
        System.out.println("編碼以後的內容 : " + encod);
        String decod = URLDecoder.decode(encod, "UTF-8");
        System.out.println("解碼以後的內容 : " + decod);
    }
}

    19.4 TCP程序設計

      在Java中使用Socket(即套接字)完成TCP程序的開發,使用此類能夠方便地簡歷可靠的、雙向的、持續的、點對點的通訊鏈接。

      在Socket的程序開發中,服務器端使用ServerSocket等待客戶端鏈接,對於Java的網絡程序來說,每個客戶端都使用Socket對象表示。

      19.4.1 ServerSocket 類與 Socket 類

        ServerSocket主要用在服務器端程序的開發上,用於接收客戶端的鏈接請求。

        ServerSocket類的經常使用方法:

        ⊙ public ServerSocket(int port)throws IOException : 建立ServerSocket實例,並指定監聽端口。

        ⊙ public Socket accept() throws IOException : 等待客戶端鏈接,此方法鏈接以前一直阻塞。

        ⊙ public InetAddress getInetAddress() : 返回服務器的IP地址。

        ⊙ public boolean isClosed() : 返回ServerSocket的關閉狀態。

        ⊙ public void close() throws IOException : 關閉ServerSocket。

        在服務器端每次運行時都要使用accept()方法等待客戶端鏈接,此方法執行以後服務器端將進入阻塞狀態,知道客戶端鏈接以後程序能夠向下繼續執行。此方法返回值類型是Socket,每個Socket都表示一個客戶端對象。

        Socket類的經常使用方法:

        ⊙ public Socket(String host,int port) throws UnknownHostException,IOException  : 構造Socket對象,同時指定要鏈接服務器的主機名稱及鏈接端口。

        ⊙ public InputStream getInputStream() throws IOException : 返回此套接字的輸入流。

        ⊙ public OutputStream getOutputStream() throws IOException : 返回此套接字的輸入流。

        ⊙ public void close() throws IOException : 關閉此Socket。

        ⊙ public boolean isClosed() : 判斷此套接字是否被關閉。

        在客戶端,程序能夠經過Socket類的getInputStream()方法取得服務器的輸入信息,在服務器端能夠經過getOutputStream()方法取得客戶端的輸出信息。

      19.4.2 第一個TCP程序

        Class : ServerSocketMain

package java_.net_.demo.java_15_5.serverSocket;

import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class ServerSocketMain {

    public static void main(String[] args) throws Exception{
        
        ServerSocket server = new ServerSocket(8888);
        Socket client = null;
        PrintStream out = null;
        int count = 1;
        while(true){
            System.out.println("等待第 " + count + " 個客戶端接入");
            client = server.accept();
            System.out.println("第 " + count + " 個客戶端已接入");
            count++;
            String resp = "Now is : " + new Date();
            out = new PrintStream(client.getOutputStream());
            out.println(resp);
        }
    }
}

        Class : SocketMain

package java_.net_.demo.java_15_5.socket;

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

public class SocketMain {

    public static void main(String[] args) throws Exception{
        Socket client = new Socket("localhost",8888);
        BufferedReader buf = null;
        buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
        String str = buf.readLine();
        System.out.println("服務器端輸出內容 :" + str);
        client.close();
        buf.close();
    }
}

      19.4.3 案例:Echo程序(BIO)

        Echo程序是一個網絡編程通訊交互的一個經典案例,稱爲迴應程序,即客戶端輸入那些內容,服務器端會在這些內容前加上「ECHO:」並將信息發回客戶端。

        本程序中將經過循環的方式使用accept(),這樣,每個客戶端執行完畢後,服務器端均可以從新等待用戶鏈接。

          Class : EchoServer

package limeNet.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServer {

    public static void main(String[] args) throws Exception {
        ServerSocket server = null;
        Socket client = null;
        PrintStream out = null;
        BufferedReader buf = null;
        server = new ServerSocket(8888);
        boolean f = true;
        while(f){
            System.out.println("服務器運行,等待客戶端鏈接。");
            client = server.accept();
            buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
            out = new PrintStream(client.getOutputStream());
            boolean flag = true;
            while(flag){
                String str = buf.readLine();
                if(null == str || "".equals(str)){
                    flag = false;
                }else{
                    if("bye".equals(str)){
                        flag = false;
                    }else{
                        out.print("ECHO : " + str);
                    }
                }
            }
            out.close();
            buf.close();
            client.close();
        }
        server.close();
    }
}

          Class : EchoClient

package limeNet.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class EchoClient {

    public static void main(String[] args) throws Exception, Exception {
        Socket client = null;
        client = new Socket("localhost",8888);
        BufferedReader input = null;
        PrintStream out = null;
        BufferedReader buf = null;
        input = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintStream(client.getOutputStream());
        buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
        boolean flag = true;
        while(flag){
            System.out.print("輸入信息:");
            String str = input.readLine();
            out.print(str);
            if("bye".equals(str)){
                flag = false;
            }else{
                String echo = buf.readLine();
                System.out.println(echo);
            }
        }
        client.close();
        buf.close();
    }
}

      19.4.4 在服務器上應用多線程

        對於服務器端來講,若是要加入多線程機制,則應該在每一個用戶鏈接以後啓動一個新的線程。

        Class : EchoThread

package limeNet.thread.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class EchoThread implements Runnable {

    private Socket accept;

    public EchoThread() {
        super();
    }
    public EchoThread(Socket accept) {
        super();
        this.accept = accept;
    }

    public void run() {
        DataInputStream in = null;
        DataOutputStream out = null;
        try {
            in = new DataInputStream(accept.getInputStream());
            out = new DataOutputStream(accept.getOutputStream());
            boolean goon = true;
            while (goon) {
                String str = in.readUTF();
                if (null == str || "".equals(str)) {
                    goon = false;
                } else {
                    if ("bye".equalsIgnoreCase(str)) {
                        goon = false;
                    } else {
                        out.writeUTF("ECHO:" + str);
                    }
                }
            }
            in.close();
            out.close();
            accept.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

        Class : EchoThreadServer

package limeNet.thread.server;

import java.net.ServerSocket;
import java.net.Socket;

public class EchoThreadServer {

    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(8888);
        while(true){
            System.out.println("服務器運行,等待客戶端鏈接。");
            Socket accept = serverSocket.accept();
            new Thread(new EchoThread(accept)).start();
        }
    }
}

        Class : EchoClient

package limeNet.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;

public class EchoClient {

    public static void main(String[] args) throws Exception, Exception {
        Socket client = null;
        client = new Socket("localhost",8888);
        DataInputStream in = null;
        DataOutputStream out = null;
        in = new DataInputStream(client.getInputStream());
        out = new DataOutputStream(client.getOutputStream());
        Scanner sc = new Scanner(System.in);
        boolean flag = true;
        while(flag){
            System.out.print("輸入信息:");
            String str = sc.nextLine();
            out.writeUTF(str);                                                                                                      
            if("bye".equals(str)){
                flag = false;
            }else{
                String echo = in.readUTF();
                System.out.println(echo);
            }
        }
        in.close();
        out.close();
        sc.close();
        client.close();
    }
}

    19.5 UDP程序設計

      19.5.1 UDP簡介

      19.5.2 UDP程序實現

        Class : UDPClient

package limeNet.udp.client;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPClient {

    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(9000);
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, 1024);
//        阻塞
        ds.receive(dp);
        String str = new String(dp.getData(),0,dp.getLength()) + "from " + dp.getAddress().getHostAddress() + " : " + dp.getPort();
        System.out.println(str);
        ds.close();
    }
}

        Class : UDPServer

package limeNet.udp.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPServer {

    public static void main(String[] args) throws IOException {
        DatagramSocket ds = null;
        DatagramPacket dp = null;
        ds = new DatagramSocket(3000);
        String str = "Hello World";
        dp = new DatagramPacket(str.getBytes(), str.length(),InetAddress.getByName("localhost"),9000);
        System.out.println("發送信息。");
        ds.send(dp);
        ds.close();
    }
}

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

相關文章
相關標籤/搜索