網絡編程入門:UDP、TCP

1 網絡編程入門

1.1概述

網絡編程:在網絡通信協議下,不同計算機運行的程序,可以進行數據傳輸。

1.2三要素

IP地址:設備在網絡中的地址,是唯一的標識。
端口:應用程序在設備中唯一的標識。
協議:數據在網絡中傳輸的規則,常見的協議有UDP協議和TCP協議。

1.2.1 IP地址

IP:全稱“互聯網協議地址”,也稱IP地址。是分配給上網設備的數字標籤。常見的ip分類爲:ip4和ip6
在這裏插入圖片描述
ip4有四個字節,共有256x256x256x256=4,294,967,296‬種取值。然而ip地址的需求量越來越大,ip4模式下ip總數總是有限的,因此有了ip6.ip6採用128位地址長度,分成8組。
在這裏插入圖片描述
常用命令
ipconfig:查看本機ip地址
ping IP地址:檢查網絡是否連通
特殊ip地址
127.0.0.1:是回送地址也稱本地迴環地址,可以表示本機的ip地址,一般用來測試使用

爲了方便我們對IP地址的獲取和操作,Java提供了一個類InetAddress供我們使用。
在這裏插入圖片描述

        InetAddress address=InetAddress.getByName("DESKTOP-7EKUN48");//參數可以是主機名或者ip
        System.out.println("獲取IP地址:"+address.getHostAddress());
        System.out.println("獲取主機名:"+ address.getHostName());

1.2.2 端口

端口:應用程序在設備中唯一的標識。
端口號:用兩個字節表示的整數,它的取值範圍是0-65535.其中0-1023之間的端口用於一些知名的網絡服務或者應用。我們自己使用1024以上的端口號就可以了。
注意:一個端口號只能被一個應用程序使用。

1.2.3 協議

協議:計算機網絡中,連接和通信的規則被稱爲網絡通信協議
UDP協議

用戶數據報協議(User Datagram Protocol)
UDP是面向無連接通信協議。
速度快,有大小限制一次最多發送64k,數據不安全,容易丟失數據。

TCP協議

傳輸控制協議(Transmission Control Protocol)
TCP協議是面向連接的通信協議。
速度慢,沒有大小限制,數據安全。

2 UDP通信程序

2.1 UDP發送數據

1、創建發送端的DatagramSocket對象
2、創建數據,並把數據打包
3、調用DatagramSocket的方法發送數據
4、釋放資源

public class Client {
    public static void main(String[] args) throws Exception{
        //1、找碼頭
        DatagramSocket ds=new DatagramSocket();
        //2、打包禮物
        /*
        DatagramPacket(byte buf[], int length, InetAddress address, int port)
        參數分別表示:打包的數據,數據長度,發送的Ip,端口
         */
        String s="送給老丈人的禮物";
        byte[] bytes=s.getBytes();
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
        //3、把禮物給碼頭
        ds.send(dp);
        //4、付錢走羊
        ds.close();
    }
}

2.2 UDP接收數據

1、創建接收端的DatagramSocket對象
2、創建一個箱子,用於接收數據
3、調用DatagramSocket的方法接收數據並將數據放入箱子中
4、解析數據包,並把數據在控制檯顯示
5、釋放資源

/**
 * UDP協議:面向無連接
 * 1、先運行接收端,再運行發送端
 * 2、如果接收端在啓動之後沒有接收到數據,那麼會死等(阻塞)
 * 3、在接收數據的時候,需要調用getLength方法,表示接收到了多少字節
 */
public class Server {
    public static void main(String[] args) throws Exception {
        //1、找碼頭-------端口號表示是從哪個端口接收的(因爲客戶端將數據送到10000端口上了,所以要從該端口獲得)
        DatagramSocket ds=new DatagramSocket(10000);
        //2、拿新箱子
        /*
            DatagramPacket(byte buf[], int length)
            接收到的數據 數據長度
         */
        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
        //3、新箱子裝禮物
        ds.receive(dp);//如果接收不到數據,會在這一行阻塞
        //4、老丈人從新箱子拿禮物
        //打印string類型的接收內容  從0到接收的最後一個字符
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        //5、拿完走羊
        ds.close();
    }
}

2.3 UDP通信程序練習(聊天室)

要求:
1、UDP發送數據:數據來自於鍵盤錄入,直到輸入的數據是886,發送數據結束。
2、UDP接收數據:因爲接收端不知道發送端什麼時候停止發送,故採用死循環接收。

public class Client {
    public static void main(String[] args) throws IOException {
        Scanner scanner=new Scanner(System.in);
        while(true){
            String data=scanner.nextLine();
            if (data.equals("886")){
                System.out.println("已停止傳送數據");
                break;
            }
            byte[] bytes = data.getBytes();
            DatagramSocket ds=new DatagramSocket();
            DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
            ds.send(dp);
            ds.close();
        }
    }
public class Server {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket(10000);
        while (true) {
            byte[] bytes=new byte[1024];
            DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
            ds.receive(dp);
            System.out.println(new String(dp.getData(),0,dp.getLength()));
        }
        //ds.close(); 不需要關閉 一直開啓
    }
}

2.4 UDP三種通信方式

2.4.1 單播

在這裏插入圖片描述
以上UDP所有例子都是與一臺服務器進行通信。屬於單播。

2.4.2 組播

在這裏插入圖片描述
組播地址:224.0.0.0 ~ 239.255.255.255。其中224.0.0.0 ~ 224.0.0.255 爲預留的組播地址,我們使用224.0.1.0以上的地址即可。
在這裏插入圖片描述

public class Client {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket();
        String data="hello 組播";
        byte[] bytes = data.getBytes();
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("224.0.1.0"),10000);
        ds.send(dp);
        ds.close();
    }
public class Server {
    public static void main(String[] args) throws IOException {
        MulticastSocket ms=new MulticastSocket(10000);
        DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
        //把當前計算機綁定組播地址,表示添加到這一組中
        ms.joinGroup(InetAddress.getByName("224.0.1.0"));
        ms.receive(dp);
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        ms.close();
    }
}

2.4.3 廣播

在這裏插入圖片描述
廣播地址:255.255.255.255

public class Client {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket();
        String s="hello 廣播";
        byte[] bytes = s.getBytes();
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("255.255.255.255"),10000);
        ds.send(dp);
        ds.close();
    }
}

public class Server {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket(10000);
        DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
        ds.receive(dp);
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        ds.close();

    }
}

3 TCP通信程序

3.1 TCP通信原理

TCP通信協議是一種可靠的網絡協議,它在通信的兩端各建立一個Socket對象。
通信之前要保證連接已經建立。
通過Socket產生IO流來進行網絡通信。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

//TCP 發送端
public class Client {
    public static void main(String[] args) throws Exception {
        //1、創建一個socket對象
        //Socket(String host, int port) 要連接的服務器ip,端口
        Socket socket=new Socket("192.168.1.16",10000);
        //2、獲取一個io流寫數據
        OutputStream out=socket.getOutputStream();
        out.write("hello tcp".getBytes());
        //3、釋放資源
        socket.close();
        out.close();
    }
}

//TCP 接收端
public class Server {
    public static void main(String[] args) throws IOException {
        //1、創建socket對象
        ServerSocket ss=new ServerSocket(10000);
        //2、等待客戶端連接
        Socket accept=ss.accept();//等不到發送端就會阻塞
        //3、獲取輸入流對象
        InputStream in=accept.getInputStream();
        int len=0;
        while((len=in.read())!=-1){
            System.out.print((char)len);
        }
        //4、釋放資源
        in.close();
        ss.close();

    }
}

3.2 TCP通信程序練習

要求:
1、客戶端:發送數據,接收服務器反饋
2、服務器:接收數據,給出反饋

public class Client {
    public static void main(String[] args) throws Exception{
        Socket socket=new Socket("192.168.1.16",10000);
        OutputStream os=socket.getOutputStream();
        os.write("hello TCP".getBytes());
        os.flush();
        socket.shutdownOutput();//僅僅關閉輸出流,並寫一個輸出標記,對socket沒有影響
        InputStream is = socket.getInputStream();
        int len;
        while((len=is.read())!=-1){
            System.out.print((char)len);
        }
        is.close();
        os.close();
        socket.close();
    }
}

public class Server {
    public static void main(String[] args) throws Exception{
        ServerSocket ss=new ServerSocket(10000);
        Socket accept=ss.accept();
        InputStream is=accept.getInputStream();
        int len=0;
        while((len=is.read())!=-1){
            System.out.print((char)len);
        }
        OutputStream os=accept.getOutputStream();
        os.write("who are you?".getBytes());
        os.flush();
        os.close();
        is.close();
        accept.close();
        ss.close();
    }
}

3.3 TCP通信程序練習(文件上傳)

要求:
1、客戶端:將本地文件上傳到服務器。接收服務器的反饋。
2、服務器:接收客戶端上傳的文件,上傳完畢之後給出反饋。
在這裏插入圖片描述

public class Client {
    public static void main(String[] args) throws Exception{
        Socket socket=new Socket("192.168.1.16",10000);
        //本地流 讀取本地文件
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("01_inetAddress/ClientDir/feder.jpg"));
        //網絡流 寫到服務器
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        int len;
        byte[] data=new byte[1024];
        while((len=bis.read(data))!=-1){
            bos.write(data,0,len);//通過網絡寫到服務器
        }
        //給服務器結束標記
        socket.shutdownOutput();

        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line="";
        while((line=br.readLine())!=null){
            System.out.println(line);
        }

        bis.close();
        socket.close();
    }
}

public class Server {
    public static void main(String[] args) throws Exception{
        ServerSocket ss=new ServerSocket(10000);
        Socket accept = ss.accept();
        //網絡流 從客戶端讀取
        BufferedInputStream bis=new BufferedInputStream(accept.getInputStream());
        //本地流 寫到文件夾中
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("01_inetAddress/ServerDir/copy_feder.jpg"));
        int len;
        byte[] data=new byte[1024];
        while((len=bis.read(data))!=-1){
            bos.write(data,0,len);
        }

        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
        bw.write("上傳成功");
        bw.newLine();
        bw.flush();

        bos.close();
        accept.close();//socket關閉 網絡流一定關閉 不用手動bis.close()
        ss.close();

    }
}

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