JavaDay25網絡

@toc

網絡編程:網絡編程是用來解決計算機和計算機之間的通訊問題;
網頁編程:基於 HDML 頁面的基礎上進行數據的交互;

一、獲取 IP 地址

  • IP 類獲取 IP 對象的方式
    使用類:InetAddress
    常用方法:
方法名 含義
getLocalHost(); 獲取本機的主機名和 IP 地址
getByName(String address); 可以通過計算機名或者 IP 地址,得到對應的 IP 對象
getHostAddress(); 返回一個 IP 地址的字符串表示方式
getHostName(); 返回主機名

以上方法使用示例:

package Demo;

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

public class Puzzle4{
    public static void main(String[] args) throws UnknownHostException {
        //獲取本機的IP地址對象
        InetAddress address = InetAddress.getLocalHost();
        System.out.println(address);
        
        //通過主機名獲取IP地址
        InetAddress address1 = InetAddress.getByName("GJXAIOU");
        System.out.println(address1);

        InetAddress address2 = InetAddress.getByName("192.168.1.1");
        System.out.println(address2);

        System.out.println(address.getHostAddress());
        System.out.println(address.getHostName());

        InetAddress[] addresses = InetAddress.getAllByName("www.taobao.com");
        for (InetAddress inetAddress : addresses) {
            System.out.println(inetAddress);
        }
    }
}

程序運行結果:

GJXAIOU/192.168.137.1
GJXAIOU/192.168.137.1
/192.168.1.1
192.168.137.1
GJXAIOU
www.taobao.com/61.155.222.102
www.taobao.com/61.155.222.103

二、UDP 中 socket

在網絡編程中所有的數據傳遞都是依賴於 Socket 來完成的,要求進行通信的兩臺計算機都要安裝有 Socket;
不同的傳輸協議有不同的 Socket;

  • UDP 下面的 socket:
    1.把數據封裝成一個數據包,面向無連接;
    2.UDP 數據報大小限制在 64kB 以內;
    3.無連接傳輸速度快但是不可靠;
    4.UDP 不區分服務端和客戶端,只有發送端和接收端;

  • UDP 下面的 Socket 使用:

    • DatagramSocket(); //獲取 UDP 的 Socket
    • DatagramPacket(byte[] buf, int length, InetAddress address, int port); //UDP 傳輸的數據包
      • buf:要打包的數據,要求數據類型是 byte 類型數組;
      • length:要打包數據的字節個數;
      • address:發送目標地址的 IP 對象;
      • port:端口號

端口號:是系統中每一個執行的程序唯一的編號,接收到的數據根據不同的端口號將數據發送給對應的程序;
序號從 0-65535,其中 0-1023 是爲系統服務的端口號,已經綁定;

  • 發送端流程:
    • 1.建立 UDP 服務,打開 UDP 協議下的 Socket;
    • 2.準備數據;
    • 3.將數據打包;
    • 4.通過 Socket 發送數據;
    • 5.Socket 關閉資源

代碼示例:

  • 發送端代碼:
package Demo;
import java.io.IOException;
import java.net.*;

public class Puzzle4{
    public static void main(String[] args) throws IOException {
        //1.建立UDP服務,打開UDP協議下的Socket,發送端Socket創建不需要任何參數
        DatagramSocket socket = new DatagramSocket();

        //2.準備數據
        String data = "hello";

        //3.數據打包
        DatagramPacket datagramPacket = new DatagramPacket (data.getBytes(), 
        data.getBytes().length, 
        InetAddress.getLocalHost(), 
        8848);

        //4.通過Socket發送數據
        socket.send(datagramPacket);

        //5.關閉資源
        socket.close();

    }
}
  • 接收端流程:
    1.建立UDP服務,監聽端口
    2.準備空數據包,用於接收數據
    3.調用UDP服務接收數據
    4.獲取數據
    5.釋放資源

接收端代碼:

package Demo;

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


public class Puzzle4Receive {
    public static void main(String[] args) throws IOException {
        //1.建立UDP服務,監聽端口
        DatagramSocket socket = new DatagramSocket(8848);

        //2.準備空數據包,接收數據
        byte[] buf = new byte[1024];
        //利用byte數據創建空數據包
        DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);

        //3.調用UDP服務,使用Socket接收數據
        socket.receive(datagramPacket);

        //4.從數據包中獲取socket接收到的數據
        //所有的數據都會被保存在byte數組中,通過調用UDP數據包的getlength方法,獲取到接收到的數據字節長度
        System.out.println(new String(buf, 0, datagramPacket.getLength()));

        //5.關閉資源
        socket.close();
    }
}

(一)搭建局域網聊天工具

chatSender.java 文件

package Chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
 * @author GJXAIOU
 * @create 2019-07-24-16:02
 */

//這裏使用多線程進行操作
public class chatSender extends Thread {
    @Override
    public void run() {
        try {
            DatagramSocket socket = new DatagramSocket();

            //system.in是鍵盤
            //這裏是將一個輸入字節流對象做成一個輸入字符流對象,提供給緩衝字符流作爲讀寫的能力
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

            String line = null;
            DatagramPacket packet = null;

            while ((line = bufferedReader.readLine()) != null){
                packet = new DatagramPacket(line.getBytes(), line.getBytes().length, 
                InetAddress.getByName("218.2.216.255"),8888); //裏面的IP地址爲廣播地址

                socket.send(packet);
            }

            socket.close();

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


chatReceive 文件

package Chat;

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

/**
 * @author GJXAIOU
 * @create 2019-07-24-16:02
 */
public class chatReceive extends Thread{
    @Override
    public void run() {
        try {
            DatagramSocket socket = new DatagramSocket(8888);

            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);

            boolean flag = true;
            while (flag){
                socket.receive(packet);
                System.out.println(packet.getAddress().getHostAddress() + ":" + new String(buf, 0,packet.getLength()));
            }

            socket.close();

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

chatMain.java 文件

package Chat;

/**
 * @author GJXAIOU
 * @create 2019-07-24-16:02
 */
public class chatMain {
    public static void main(String[] args) {
        chatSender chatSender = new chatSender();
        chatReceive chatReceive = new chatReceive();
        chatSender.start();
        chatReceive.start();

    }
}

(二)模擬飛秋髮送數據

因此這裏只有發送端程序

package Chat;

import java.io.IOException;
import java.net.*;

/**
 * @author GJXAIOU
 * @create 2019-07-24-16:45
 */
/*FeiQ的數據格式:
  version:time:sender:ip:flag:content
  版本號   時間  發送人  IP地址
 */
public class FeiQ {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        String data = getData("hello");

        DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getByName("192.168.1.1"), 2425);
        socket.send(packet);
        socket.close();
    }


    private static String getData(String content){
        StringBuilder data = new StringBuilder();

        data.append("1.0:");
        data.append(System.currentTimeMillis() + ":");
        data.append("匿名君");
        data.append("10.1.1.1");
        data.append("32:");
        data.append(content);

        return data.toString();
    }

}


三、TCP 中 Socket

  • TCP 特徵:
    1.TCP 是完全基於 IO 流進行數據傳輸的,面向連接;
    2.TCP 進行數據傳遞時候沒有顯示數據報的大;
    3.TCP 面向連接,必須通過三次握手之後才能保證數據的傳輸通道是完整的;
    4.TCP 面向連接,速度相對較慢;
    5.TCP 是區分客戶端和服務器;

  • TCP 協議下的 Socket
    Socket(服務器 IP 地址對象, 服務器軟件對應的端口號); 創建 TCP 協議下的端口號,並且。。。。
    ServerSocket(); 服務器的 Socket,開始服務器服務,準備捕獲 Socket

TCP 客戶端流程:
1.建立 TCP 客戶端連接,申請連接服務器,需要服務器 IP 地址對象和對應的程序端口號;
2.獲取對應的流對象;
3.寫入或者讀取數據;
4.關閉資源;

發送端:

package IP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;


/**
 * @author GJXAIOU
 * @create 2019-07-24-17:11
 */
public class IpSocket {
    public static void main(String[] args) throws IOException {
        //1.建立客戶端Socket,申請連接服務器,需要服務器的IP地址和對應程序的端口號
        Socket socket = new Socket(InetAddress.getLocalHost(), 8000);

        //2.發送數據給服務器,需要獲取Socket的輸出流對象
        OutputStream os = socket.getOutputStream();

        //使用OutputStream方法發送數據到服務器,也就是輸出數據
        os.write("你好,服務器".getBytes());

        //3.獲取Socket的InputStream
        InputStream inputStream = socket.getInputStream();
        byte[] buf = new byte[1024];
        int length = inputStream.read(buf);

        System.out.println("服務器說:" + new String(buf, 0, length));

        socket.close();
    }
}

服務器接收端:

package IP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author GJXAIOU
 * @create 2019-07-24-17:23
 */
public class IpService {
    public static void main(String[] args) throws IOException {
        //1.使用ServiceSocket開始TCP服務器,監聽指定端口,準備捕獲從客戶端申請Socket連接
        ServerSocket serverSocket = new ServerSocket(8000);

        //2.接受客戶端連接,得到客戶端Socket對象
        Socket accept = serverSocket.accept();

        //3.獲取從客戶端得到的Socket對象的輸入流
        InputStream inputStream = accept.getInputStream();

        byte[] buf = new byte[1024];
        int length = inputStream.read(buf);
        System.out.println("客戶端說:" + new String(buf, 0, length));

        //4.獲取Socket的輸出流對象,給客戶端發送數據
        OutputStream outputStream = accept.getOutputStream();

        outputStream.write("你好,客戶端:".getBytes());

        //關閉ServerSocket,即關閉TCP協議下的服務器程序
        serverSocket.close();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章