1. 程式人生 > >java:網路程式設計(InetAddress,InetSocketAddress,URL,TCP(Socket與SeverSocket),TCP與UDP的區別)

java:網路程式設計(InetAddress,InetSocketAddress,URL,TCP(Socket與SeverSocket),TCP與UDP的區別)

 

InerAddress:

/**IP地址:在網路上唯一標示一臺計算機
* 埠號:標示計算機上不同的應用程式
* java.net.InetAddress類:此類表示網際網路協議 (IP) 地址。
* 常用方法:
* getByName(String host) 在給定主機名的情況下確定主機的 IP 地址。
* getHostName() 獲取此 IP地址的主機名。
* getHostAddress()返回 IP 地址字串(以文字表現形式)。
* getLocalHost() 返回本地主機。
* getAllByName(String host) 在給定主機名的情況下,根據系統上配置的名稱服務返回其 IP 地址所組成的陣列。
*
*/

複製程式碼
public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //在給定主機名的情況下確定主機的 IP 地址。
//            InetAddress inetAddress = InetAddress.getByName("P-PC");
            InetAddress inetAddress = InetAddress.getLocalHost();//獲取本地主機
            System.out
.println(inetAddress); String hostName = inetAddress.getHostName(); System.out.println("主機名:"+hostName); String ip = inetAddress.getHostAddress(); System.out.println("IP地址:"+ip); //根據主機名或域名獲取其IP地址 InetAddress[] ids = InetAddress.getAllByName("
www.baidu.com"); for (InetAddress inetAddress2 : ids) { System.out.println(inetAddress2); } } catch (UnknownHostException e) { e.printStackTrace(); } } }
複製程式碼

InetSocketAddress:

*java.net.InetSocketAddress類:此類實現 IP 套接字地址(IP 地址 + 埠號)。
*構造方法
*InetSocketAddress(InetAddress addr, int port)根據 IP 地址和埠號建立套接字地址。
*InetSocketAddress(String hostname, int port) 根據主機名和埠號建立套接字地址。
*常用的方法:
* getAddress():獲取 InetAddress。
* getPort() 獲取埠號。
* toString() 構造此 InetSocketAddress 的字串表示形式。(主機名/Ip:埠號)
* getHostName()獲取 主機名。

複製程式碼
public class TestInetSocketAddress {
    public static void main(String[] args) {
//        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",3306);
        try {
            InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), 3306);
            System.out.println(socketAddress);
            InetAddress inetAddress = socketAddress.getAddress();
            System.out.println("主機資訊:"+inetAddress);
            int port = socketAddress.getPort();
            System.out.println("埠號:"+port);
            String hostName = socketAddress.getHostName();
            System.out.println("主機名:"+hostName);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

URL:

*URL:統一資源定位符
*組成部分:協議,主機名或IP,埠號,資源路徑
*java.net.URL類:代表一個統一資源定位符,它是指向網際網路“資源”的指標
* 常用的構造方法
* URL(String spec) 根據 String 表示形式建立 URL 物件。
* URL(String protocol, String host, int port, String file) 根據指定 protocol、host、port 號和 file 建立 URL 物件。
* 常用的方法:
* getProtocol()獲取此 URL 的協議名稱。
* getHost()獲取此 URL 的主機名(如果適用)。
* getPort() 獲取此 URL 的埠號。
* getFile()獲取此 URL 的檔名。
* getDefaultPort()獲取與此 URL 關聯協議的預設埠號。
* getPath()獲取此 URL 的路徑部分。
* ...

複製程式碼
public class TestURL {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.baidu.com/index.html#aa?cansu=bjsxt");
            String protocol = url.getProtocol();
            System.out.println("協議:"+protocol);
            String host = url.getHost();
            System.out.println("主機名:"+host);
            int port = url.getPort();
            System.out.println("埠號:"+port);
            int defualtPort = url.getDefaultPort();
            System.out.println("預設埠:"+defualtPort);
            String file = url.getFile();
            System.out.println("資源路徑:"+file);
            String path = url.getPath();
            System.out.println("資源路徑:"+path);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

URL類
* InputStream openStream() 開啟到此 URL 的連線並返回一個用於從該連線讀入的 InputStream。

複製程式碼
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class WebSpider {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://channel.jd.com/men.html");
            InputStream ips = url.openStream();
            InputStreamReader isr = new InputStreamReader(ips);//將位元組流轉換為字元流
            BufferedReader br = new BufferedReader(isr);
            String str;
            while((str=br.readLine())!=null){
                System.out.println(str);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
複製程式碼

 Socket與SeverSocket資訊的傳遞:

複製程式碼
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/** 
 * java.net.ServerSocket類:此類實現伺服器套接字。伺服器套接字等待請求通過網路傳入
 * 構造方法:
 * ServerSocket(int port)建立繫結到特定埠的伺服器套接字。
 * 
 * 常用方法:
 * accept() 偵聽並接受到此套接字的連線。
 * close() 關閉此套接字。
 * 
 * 伺服器端
 */
public class SimpleServer {
    public static void main(String[] args) {
        try {
            System.out.println("------伺服器端啟動------");
            //1.建立伺服器端的套接字並指定埠
            ServerSocket serverSocket = new ServerSocket(8888);
            //2.偵聽並接受到此套接字的連線。
            Socket socket = serverSocket.accept();
            //3.從套接字中獲取一個輸入流
            InputStream ips = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(ips);
            char[] cs = new char[1024];
            int len = isr.read(cs);
            String message = new String(cs, 0, len);
            System.out.println("客戶端訊息:"+message);
            isr.close();
            socket.close();
            serverSocket.close();
            System.out.println("伺服器資料接收完畢!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼 複製程式碼
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *java.net.Socket類:此類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩臺機器間通訊的端點。 
 *構造方法:
 *Socket(InetAddress address, int port)建立一個流套接字並將其連線到指定 IP 地址的指定埠號。
 *Socket(String host, int port) 建立一個流套接字並將其連線到指定主機上的指定埠號。
 *常用方法:
 *getOutputStream()返回此套接字的輸出流。
 *getInputStream()  返回此套接字的輸入流。
 *close()關閉此套接字。
 *客戶端
 */
public class SimpleClient {
    public static void main(String[] args) {
        try {
            System.out.println("-------客戶端啟動-------");
            //1.建立一個套接字並將其連線到指定的IP地址的指定埠
            Socket socket = new Socket("127.0.0.1",8888);
            //2.獲取套接字的輸出流,用於輸出資料
            OutputStream ops = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(ops);
            osw.write("你好!");
            osw.flush();
            osw.close();
            socket.close();
            System.out.println("客戶端資料傳送完畢!");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
     }
}
複製程式碼

 根據使用者輸入的賬號密碼,從伺服器上判斷是否正確並傳遞資訊回來:

複製程式碼
import java.io.Serializable;
/**
 * 如果要對該物件進行序列化,就必須實現Serializable介面
 * 封裝使用者名稱和密碼資訊
 */
public class User implements Serializable{
    private String userName;
    private String password;
    public User(){
        
    }
    public User(String userName,String password){
        this.userName=userName;
        this.password=password;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}
複製程式碼 複製程式碼
import java.io.DataInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * 客戶端:
 * 1.獲取使用者名稱和密碼
 * 2.將使用者名稱和密碼封裝成User物件
 * 3.使用物件流將user物件發生到伺服器端
 * 4.讀取伺服器的響應訊息
 * 5.釋放資源
 */
public class LoginClient {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //獲取輸入的使用者名稱和密碼
        System.out.println("請輸入使用者名稱:");
        String userName = input.next();
        System.out.println("請輸入密碼:");
        String password = input.next();
        //將使用者名稱和密碼封裝成User物件
        User user = new User(userName,password);
        try {
            //建立Socket物件
            Socket socket = new Socket("127.0.0.1",6666);
            //獲取輸出流
            OutputStream ops = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(ops);
            //使用物件流將user物件傳送到伺服器端
            oos.writeObject(user);
            oos.flush();
            //獲取伺服器端響應訊息
            InputStream ips = socket.getInputStream();
            DataInputStream dis = new DataInputStream(ips);
            String str = dis.readUTF();
            System.out.println(str);
            //釋放資源
            dis.close();
            oos.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    
}
複製程式碼 複製程式碼
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 伺服器端:
 * 1.獲取客戶端傳送的user物件(封裝了使用者名稱和密碼)
 * 2.判斷使用者名稱和密碼是否合法
 * 3.如果合法,向客戶端傳送"恭喜你,登陸成功!";否則向客戶端傳送"使用者名稱或密碼有誤!"
 * 4.釋放資源
 */
public class LoginServer {
    public static void main(String[] args) {
        try {
            //1.獲取客戶端傳送的使用者名稱和密碼資訊
            ServerSocket serverSocket = new ServerSocket(6666);
            Socket socket = serverSocket.accept();
            InputStream ips = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(ips);
            User user = (User)ois.readObject();
            //2.判斷使用者名稱和密碼是否正確
            String message;
            if("zzsxt".equals(user.getUserName())&&"zzsxt".equals(user.getPassword())){
                message="恭喜你,登陸成功!";
            }else{
                message="使用者名稱或密碼有誤!";
            }
            //3.建立輸出流向客戶端傳送訊息
            OutputStream ops = socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(ops);
            dos.writeUTF(message);
            dos.flush();
            //4.釋放資源
            ois.close();
            dos.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

 方法2:

複製程式碼
/**
 * 伺服器端:
 * 1.獲取客戶端傳送的user物件(封裝了使用者名稱和密碼)
 * 2.判斷使用者名稱和密碼是否合法
 * 3.如果合法,向客戶端傳送"恭喜你,登陸成功!";否則向客戶端傳送"使用者名稱或密碼有誤!"
 * 4.釋放資源
 */
public class LoginServer {
    //用於儲存使用者名稱和密碼的資訊,利用使用者名稱做鍵,利用密碼做值
    static Map<String,String> map = new HashMap<String,String>();
    //初始化map
    static{
        map.put("zzsxt", "zzsxt");
        map.put("bjsxt", "bjsxt");
        map.put("whsxt", "whsxt");
    }
    static int count=0;//第幾位訪客
    
    public static void main(String[] args) {
        //1.獲取客戶端傳送的使用者名稱和密碼資訊
        ServerSocket serverSocket=null;
        Socket socket=null;
        ObjectInputStream ois =null;
        DataOutputStream dos=null;
        try {
            serverSocket = new ServerSocket(6666);
            while(true){
                socket = serverSocket.accept();
                InputStream ips = socket.getInputStream();
                ois = new ObjectInputStream(ips);
                User user = (User)ois.readObject();
                //2.判斷使用者名稱和密碼是否正確
                String userName = user.getUserName();//獲取使用者輸入的使用者名稱 aa
                String password = user.getPassword();//獲取使用者輸入的密碼
                String upass=map.get(userName);
                String message;
                if(upass!=null&&upass.equals(password)){
                    count++;//計數
                    message="恭喜你,登陸成功!您是第"+count+"位訪客";
                }else{
                    message="使用者名稱或密碼有誤!";
                }
                //3.建立輸出流向客戶端傳送訊息
                OutputStream ops = socket.getOutputStream();
                dos = new DataOutputStream(ops);
                dos.writeUTF(message);
                dos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                //4.釋放資源
                ois.close();
                dos.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }
}
複製程式碼

 方法3:轉換為多執行緒互動

複製程式碼
import java.io.Serializable;
/**
 * 如果要對該物件進行序列化,就必須實現Serializable介面
 * 封裝使用者名稱和密碼資訊
 */
public class User implements Serializable{
    private String userName;
    private String password;
    public User(){
        
    }
    public User(String userName,String password){
        this.userName=userName;
        this.password=password;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "User [userName=" + userName + ", password=" + password + "]";
    }
    
}
複製程式碼 複製程式碼
public class LoginClient {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //獲取輸入的使用者名稱和密碼
        System.out.println("請輸入使用者名稱:");
        String userName = input.next();
        System.out.println("請輸入密碼:");
        String password = input.next();
        //將使用者名稱和密碼封裝成User物件
        User user = new User(userName,password);
        try {
            //建立Socket物件
            Socket socket = new Socket("127.0.0.1",6666);
            //獲取輸出流
            OutputStream ops = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(ops);
            //使用物件流將user物件傳送到伺服器端
            oos.writeObject(user);
            oos.flush();
            //獲取伺服器端響應訊息
            InputStream ips = socket.getInputStream();
            DataInputStream dis = new DataInputStream(ips);
            String str = dis.readUTF();
            System.out.println(str);
            //釋放資源
            dis.close();
            oos.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}
複製程式碼 複製程式碼
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * 用於處理客戶端請求的執行緒
 * @author Administrator
 *
 */
public class ServerThread extends Thread{
    private Socket socket;
    //用於儲存使用者名稱和密碼的資訊,利用使用者名稱做鍵,利用密碼做值
    static Map<String,String> map = new HashMap<String,String>();
    //初始化map
    static{
        map.put("zzsxt", "zzsxt");
        map.put("bjsxt", "bjsxt");
        map.put("whsxt", "whsxt");
    }
    static int count=0;//第幾位訪客
    //構造方法
    public ServerThread(Socket socket){
        this.socket=socket;
    }
    /**
     * 處理客戶端請求
     */
    @Override
    public void run() {
        ObjectInputStream ois =null;
        DataOutputStream dos=null;
        try {
            InputStream ips = socket.getInputStream();
            ois = new ObjectInputStream(ips);
            User user = (User)ois.readObject();
            //2.判斷使用者名稱和密碼是否正確
            String userName = user.getUserName();//獲取使用者輸入的使用者名稱 aa
            String password = user.getPassword();//獲取使用者輸入的密碼
            String upass=map.get(userName);
            String message;
            if(upass!=null&&upass.equals(password)){
                count++;//計數
                message="恭喜你,登陸成功!您是第"+count+"位訪客";
            }else{
                message="使用者名稱或密碼有誤!";
            }
            //3.建立輸出流向客戶端傳送訊息
            OutputStream ops = socket.getOutputStream();
            dos = new DataOutputStream(ops);
            dos.writeUTF(message);
            dos.flush();
        } catch (IOException |ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                ois.close();
                dos.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
複製程式碼 複製程式碼
/**
 * 面臨的問題:
 *     當多個使用者同時登陸時,只能排隊等待。
 * 解決方案:使用多執行緒進行解決,為每一個客戶請求建立執行緒,為其提供服務。
 * 
 * 伺服器端:
 * 1.獲取客戶端傳送的user物件(封裝了使用者名稱和密碼)
 * 2.判斷使用者名稱和密碼是否合法
 * 3.如果合法,向客戶端傳送"恭喜你,登陸成功!";否則向客戶端傳送"使用者名稱或密碼有誤!"
 * 4.釋放資源
 * 
 */
public class LoginServer {
    
    public static void main(String[] args) {
        //1.獲取客戶端傳送的使用者名稱和密碼資訊
        ServerSocket serverSocket=null;
        try {
            serverSocket = new ServerSocket(6666);
            while(true){
                Socket socket = serverSocket.accept();
                //啟動執行緒,處理使用者請求
                new ServerThread(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
複製程式碼

 

 

TCP與UDP的區別:

1.TCP與UDP基本區別
  1.基於連線與無連線,TCP是面向連線,UDP是不面向連線;
  2.TCP要求系統資源較多效率低,UDP較佔用資源少; 
  3.UDP程式結構較簡單,TCP點到點的通訊,UDP可以廣播發送 ;
  4.流模式(TCP)與資料報模式(UDP); 
  5.TCP保證資料正確性,UDP可能丟包(傳送不管對方是否準備好,接收方收到也無確認); 
  6.TCP保證資料順序,UDP不保證 ;


  
2.UDP應用場景:
  1.面向資料報方式
  2.網路資料大多為短訊息 
  3.擁有大量Client
  4.對資料安全性無特殊要求
  5.網路負擔非常重,但對響應速度要求高
 
3.具體程式設計時的區別
   1.socket()的引數不同 
   2.UDP Server不需要呼叫listen和accept 
   3.UDP收發資料用sendto/recvfrom函式 
   4.TCP:地址資訊在connect/accept時確定 
   5.UDP:在sendto/recvfrom函式中每次均 需指定地址資訊 
   6.UDP:shutdown函式無效

 

 

InerAddress:

/**IP地址:在網路上唯一標示一臺計算機
* 埠號:標示計算機上不同的應用程式
* java.net.InetAddress類:此類表示網際網路協議 (IP) 地址。
* 常用方法:
* getByName(String host) 在給定主機名的情況下確定主機的 IP 地址。
* getHostName() 獲取此 IP地址的主機名。
* getHostAddress()返回 IP 地址字串(以文字表現形式)。
* getLocalHost() 返回本地主機。
* getAllByName(String host) 在給定主機名的情況下,根據系統上配置的名稱服務返回其 IP 地址所組成的陣列。
*
*/

複製程式碼
public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //在給定主機名的情況下確定主機的 IP 地址。
//            InetAddress inetAddress = InetAddress.getByName("P-PC");
            InetAddress inetAddress = InetAddress.getLocalHost();//獲取本地主機
            System.out.println(inetAddress);
            String hostName = inetAddress.getHostName();
            System.out.println("主機名:"+hostName);
            String ip = inetAddress.getHostAddress();
            System.out.println("IP地址:"+ip);
            //根據主機名或域名獲取其IP地址
            InetAddress[] ids = InetAddress.getAllByName("www.baidu.com");
            for (InetAddress inetAddress2 : ids) {
                System.out.println(inetAddress2);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

InetSocketAddress:

*java.net.InetSocketAddress類:此類實現 IP 套接字地址(IP 地址 + 埠號)。
*構造方法
*InetSocketAddress(InetAddress addr, int port)根據 IP 地址和埠號建立套接字地址。
*InetSocketAddress(String hostname, int port) 根據主機名和埠號建立套接字地址。
*常用的方法:
* getAddress():獲取 InetAddress。
* getPort() 獲取埠號。
* toString() 構造此 InetSocketAddress 的字串表示形式。(主機名/Ip:埠號)
* getHostName()獲取 主機名。

複製程式碼
public class TestInetSocketAddress {
    public static void main(String[] args) {
//        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",3306);
        try {
            InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), 3306);
            System.out.println(socketAddress);
            InetAddress inetAddress = socketAddress.getAddress();
            System.out.println("主機資訊:"+inetAddress);
            int port = socketAddress.getPort();
            System.out.println("埠號:"+port);
            String hostName = socketAddress.getHostName();
            System.out.println("主機名:"+hostName);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

URL:

*URL:統一資源定位符
*組成部分:協議,主機名或IP,埠號,資源路徑
*java.net.URL類:代表一個統一資源定位符,它是指向網際網路“資源”的指標
* 常用的構造方法
* URL(String spec) 根據 String 表示形式建立 URL 物件。
* URL(String protocol, String host, int port, String file) 根據指定 protocol、host、port 號和 file 建立 URL 物件。
* 常用的方法:
* getProtocol()獲取此 URL 的協議名稱。
* getHost()獲取此 URL 的主機名(如果適用)。
* getPort() 獲取此 URL 的埠號。
* getFile()獲取此 URL 的檔名。
* getDefaultPort()獲取與此 URL 關聯協議的預設埠號。
* getPath()獲取此 URL 的路徑部分。
* ...

複製程式碼
public class TestURL {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://www.baidu.com/index.html#aa?cansu=bjsxt");
            String protocol = url.getProtocol();
            System.out.println("協議:"+protocol);
            String host = url.getHost();
            System.out.println("主機名:"+host);
            int port = url.getPort();
            System.out.println("埠號:"+port);
            int defualtPort = url.getDefaultPort();
            System.out.println("預設埠:"+defualtPort);
            String file = url.getFile();
            System.out.println("資源路徑:"+file);
            String path = url.getPath();
            System.out.println("資源路徑:"+path);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

URL類
* InputStream openStream() 開啟到此 URL 的連線並返回一個用於從該連線讀入的 InputStream。

複製程式碼
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class WebSpider {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://channel.jd.com/men.html");
            InputStream ips = url.openStream();
            InputStreamReader isr = new InputStreamReader(ips);//將位元組流轉換為字元流
            BufferedReader br = new BufferedReader(isr);
            String str;
            while((str=br.readLine())!=null){
                System.out.println(str);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
複製程式碼

 Socket與SeverSocket資訊的傳遞:

複製程式碼
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/** 
 * java.net.ServerSocket類:此類實現伺服器套接字。伺服器套接字等待請求通過網路傳入
 * 構造方法:
 * ServerSocket(int port)建立繫結到特定埠的伺服器套接字。
 * 
 * 常用方法:
 * accept() 偵聽並接受到此套接字的連線。
 * close() 關閉此套接字。
 * 
 * 伺服器端
 */
public class SimpleServer {
    public static void main(String[] args) {
        try {
            System.out.println("------伺服器端啟動------");
            //1.建立伺服器端的套接字並指定埠
            ServerSocket serverSocket = new ServerSocket(8888);
            //2.偵聽並接受到此套接字的連線。
            Socket socket = serverSocket.accept();
            //3.從套接字中獲取一個輸入流
            InputStream ips = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(ips);
            char[] cs = new char[1024];
            int len = isr.read(cs);
            String message = new String(cs, 0, len);
            System.out.println("客戶端訊息:"+message);
            isr.close();
            socket.close();
            serverSocket.close();
            System.out.println("伺服器資料接收完畢!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼 複製程式碼
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *java.net.Socket類:此類實現客戶端套接字(也可以就叫“套接字”)。套接字是兩臺機器間通訊的端點。 
 *構造方法:
 *Socket(InetAddress address, int port)建立一個流套接字並將其連線到指定 IP 地址的指定埠號。
 *Socket(String host, int port) 建立一個流套接字並將其連線到指定主機上的指定埠號。
 *常用方法:
 *getOutputStream()返回此套接字的輸出流。
 *getInputStream()  返回此套接字的輸入流。
 *close()關閉此套接字。
 *客戶端
 */
public class SimpleClient {
    public static void main(String[] args) {
        try {
            System.out.println("-------客戶端啟動-------");
            //1.建立一個套接字並將其連線到指定的IP地址的指定埠
            Socket socket = new Socket("127.0.0.1",8888);
            //2.獲取套接字的輸出流,用於輸出資料
            OutputStream ops = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(ops);
            osw.write("你好!");
            osw.flush();
            osw.close();
            socket.close();
            System.out.println("客戶端資料傳送完畢!");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
     }
}
複製程式碼

 根據使用者輸入的賬號密碼,從伺服器上判斷是否正確並傳遞資訊回來:

複製程式碼
import java.io.Serializable;
/**
 * 如果要對該物件進行序列化,就必須實現Serializable介面
 * 封裝使用者名稱和密碼資訊
 */
public class User implements Serializable{
    private String userName;
    private String password;
    public User(){
        
    }
    public User(String userName,String password){
        this.userName=userName;
        this.password=password;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}
複製程式碼 複製程式碼
import java.io.DataInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * 客戶端:
 * 1.獲取使用者名稱和密碼
 * 2.將使用者名稱和密碼封裝成User物件
 * 3.使用物件流將user物件發生到伺服器端
 * 4.讀取伺服器的響應訊息
 * 5.釋放資源
 */
public class LoginClient {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //獲取輸入的使用者名稱和密碼
        System.out.println("請輸入使用者名稱:");
        String userName = input.next();
        System.out.println("請輸入密碼:");
        String password = input.next();
        //將使用者名稱和密碼封裝成User物件
        User user = new User(userName,password);
        try {
            //建立Socket物件
            Socket socket = new Socket("127.0.0.1",6666);
            //獲取輸出流
            OutputStream ops = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(ops);
            //使用物件流將user物件傳送到伺服器端
            oos.writeObject(user);
            oos.flush();
            //獲取伺服器端響應訊息
            InputStream ips = socket.getInputStream();
            DataInputStream dis = new DataInputStream(ips);
            String str = dis.readUTF();
            System.out.println(str);
            //釋放資源
            dis.close();
            oos.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    
}
複製程式碼 複製程式碼
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 伺服器端:
 * 1.獲取客戶端傳送的user物件(封裝了使用者名稱和密碼)
 * 2.判斷使用者名稱和密碼是否合法
 * 3.如果合法,向客戶端傳送"恭喜你,登陸成功!";否則向客戶端傳送"使用者名稱或密碼有誤!"
 * 4.釋放資源
 */
public class LoginServer {
    public static void main(String[] args) {
        try {
            //1.獲取客戶端傳送的使用者名稱和密碼資訊
            ServerSocket serverSocket = new ServerSocket(6666);
            Socket socket = serverSocket.accept();
            InputStream ips = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(ips);
            User user = (User)ois.readObject();
            //2.判斷使用者名稱和密碼是否正確
            String message;
            if("zzsxt".equals(user.getUserName())&&"zzsxt".equals(user.getPassword())){
                message="恭喜你,登陸成功!";
            }else{
                message="使用者名稱或密碼有誤!";
            }
            //3.建立輸出流向客戶端傳送訊息
            OutputStream ops = socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(ops);
            dos.writeUTF(message);
            dos.flush();
            //4.釋放資源
            ois.close();
            dos.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
    }
}
複製程式碼

 方法2:

複製程式碼
/**
 * 伺服器端:
 * 1.獲取客戶端傳送的user物件(封裝了使用者名稱和密碼)
 * 2.判斷使用者名稱和密碼是否合法
 * 3.如果合法,向客戶端傳送"恭喜你,登陸成功!";否則向客戶端傳送"使用者名稱或密碼有誤!"
 * 4.釋放資源
 */
public class LoginServer {
    //用於儲存使用者名稱和密碼的資訊,利用使用者名稱做鍵,利用密碼做值
    static Map<String,String> map = new HashMap<String,String>();
    //初始化map
    static{
        map.put("zzsxt", "zzsxt");
        map.put("bjsxt", "bjsxt");
        map.put("whsxt", "whsxt");
    }
    static int count=0;//第幾位訪客
    
    public static void main(String[] args) {
        //1.獲取客戶端傳送的使用者名稱和密碼資訊
        ServerSocket serverSocket=null;
        Socket socket=null;
        ObjectInputStream ois =null;
        DataOutputStream dos=null;
        try {
            serverSocket = new ServerSocket(6666);
            while(true){
                socket = serverSocket.accept();
                InputStream ips = socket.getInputStream();
                ois = new ObjectInputStream(ips);
                User user = (User)ois.readObject();
                //2.判斷使用者名稱和密碼是否正確
                String userName = user.getUserName();//獲取使