IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> java - 网络编程TCP/IP -> 正文阅读

[网络协议]java - 网络编程TCP/IP

概述

TCP:类似于打电话这种,接通后双方开始通话。
UDP:类似于发短信这种,一方发送一方接收。

计算机网络

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

网络编程的目的

传播交流信息,数据交换,通信。

网络编程中方的主要问题

  • 如何准确定位到网络上的一台或多台主机
  • 找到主机之后如何通信

网络通信的要素

  • IP和端口号
  • 网络通信协议

TCP/IP参考模型

在这里插入图片描述

IP

IP地址:InetAddress

  • 唯一定位一台网络上的计算机
  • 127.0.0.1:本机localhost
  • IP地址的分类:ipv4 / ipv6、公网/私网

获取ip

package com.zls.demo01;

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

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress2 = InetAddress.getByName("localhost");
            System.out.println(inetAddress2);
            InetAddress inetAddress3 = InetAddress.getLocalHost();
            System.out.println(inetAddress3);

            //查询网站ip地址
            InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress4);

            //常用方法
            System.out.println(inetAddress4.getAddress());
            System.out.println(inetAddress4.getCanonicalHostName()); //规范的名称
            System.out.println(inetAddress4.getHostAddress()); //ip
            System.out.println(inetAddress4.getHostName()); //域名

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

端口

概念

端口表示计算机上的一个程序的进程。

  • 不同的进程 有不同的端口号,用于区分软件
  • 单个协议下端口号不能冲突
  • 端口号分类:
    • 公有端口: 0 ~ 1023。
      HTTP:80;HTTPS:443;FTP:21;Telent:23;
    • 私有端口: 1024 ~ 49151。分配给用户或者程序员
      Tomcat:8080;MySQL:3306;Oracle:1521;
    • 动态端口: 49152 ~ 65535

关于端口的指令

netstat -ano #查看所有端口
netstat -ano|findstr "5900" #查看指定端口
tasklist|findstr "8696" #查看指定端口的进程
Ctrl + Shift + Esc #打开任务管理器的快捷键

获取端口

package com.zls.demo01;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
        System.out.println(socketAddress);
        System.out.println(socketAddress.getPort());
    }
}

在这里插入图片描述

通信协议

实现消息传递

模拟服务端

  1. 建立服务器的端口 ServerSocket
  2. 等待用户的链接
  3. 接收用户的消息
package com.zls.demo02;

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

//服务端
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.需要一个地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端链接
            socket = serverSocket.accept();
            //3.读取客户端的消息
            is = socket.getInputStream();

            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1){
                baos.write(buffer,0,len);
            }
            System.out.println(baos.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            if (baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

模拟客户端

  1. 连接服务器Socket
  2. 发送消息
package com.zls.demo02;

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

//客户端
public class TcpClientDemo01 {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.需要知道服务器的地址、端口号
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2.创建一个Socket链接
            socket = new Socket(serverIP,port);
            //3.发送消息 IO源
            os = socket.getOutputStream();
            os.write("你好世界".getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

结果

在运行服务器端后在运行客户端,服务器端就能接收到客户端发来的消息
在这里插入图片描述

实现文件上传

模拟服务端

  1. 建立服务器的端口 ServerSocket
  2. 等待用户的链接
  3. 接收用户的消息
package com.zls.demo02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建服务(端口)
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端链接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端链接
        //3.获取输入流
        InputStream is = socket.getInputStream();

        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        //补充:通知客户端我接收完毕了
        OutputStream os = socket.getOutputStream();
        os.write(("我接收完毕了").getBytes());

        //关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

模拟客户端

  1. 连接服务器Socket
  2. 发送消息
package com.zls.demo02;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个Socket链接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();

        //3.文件流 读取文件
        FileInputStream fis = new FileInputStream(new File("tx.jpg"));
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        //通知服务器传输完毕
        socket.shutdownOutput();//已经传输完毕了

        //确定服务器接收完毕,再断开链接
        InputStream inputStream = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len2 = inputStream.read(buffer2)) != -1){
            baos.write(buffer2,0,len2);
        }

        System.out.println(baos.toString());


        //5.关闭资源
        fis.close();
        os.close();
        socket.close();
        baos.close();
        inputStream.close();

    }
}

结果

在这里插入图片描述

UDP

发送消息

模拟服务端

(流程在代码注释中)

package com.zls.demo03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//要等待客户端的链接
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0, packet.getLength()));

        //关闭链接
        socket.close();

    }
}

模拟客户端

(流程在代码注释中)

package com.zls.demo03;

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

//不需要链接服务器
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //2.建个包
        String msg = "你好呀,服务器";

        //发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //数据,数据长度起始,发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
        //3.发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }
}

结果

在这里插入图片描述

实现聊天(连续发送)

模拟接收端

package com.zls.demo03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpReceiveDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);

        while(true){
            //准备 接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet);//阻塞式接收包裹

            byte[] data = packet.getData();
            String receiveData = new String(data, 0, packet.getLength());

            System.out.println(receiveData);

            //断开链接
            if (receiveData.equals("bye"))
                break;
        }

        socket.close();
    }
}

模拟发送端

package com.zls.demo03;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);

        //准备数据:从控制台读取 System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while (true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));

            socket.send(packet);
            if (data.equals("bye"))
                break;
        }

        socket.close();
    }
}

结果

成功发送:
在这里插入图片描述
成功接收:
在这里插入图片描述

实现在线咨询(双发都可以发送和接收)

要通过线程实现

发送类

package com.zls.demo03;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;

    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort) {
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;

        try {
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            String data = null;
            try {
                data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));

                socket.send(packet);
                if (data.equals("bye"))
                    break;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

接收类

package com.zls.demo03;

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

public class TalkReceive implements Runnable{

    DatagramSocket socket = null;

    private int port;
    private String msgFrom;

    public TalkReceive(int port, String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        while(true){

            try {
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//阻塞式接收包裹
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, packet.getLength());

                System.out.println(msgFrom + ":" + receiveData);

                //断开链接
                if (receiveData.equals("bye"))
                    break;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        socket.close();
    }
}

开启线程

注意端口的对应关系
在这里插入图片描述

结果

学生视角:
在这里插入图片描述
老师视角:
在这里插入图片描述

URL

统一资源定位器:定位互联网上的某一个资源。

实现在网站上下载资源:
(该网址是提前打开tomcat放置的一个文件)

package com.zls.demo04;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URLDemo01 {
    public static void main(String[] args) throws Exception {
        //1.下载地址
        URL url = new URL("http://localhost/zls/secretFile.txt");

        //2.链接到这个资源 HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("secretFile.txt");

        byte[] buffer = new byte[1024];
        int len;
        while((len = inputStream.read(buffer)) != -1){
            fos.write(buffer,0,len); //这出这个数据
        }

        fos.close();;
        inputStream.close();
        urlConnection.disconnect();

    }
}

在这里插入图片描述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-05-25 11:44:24  更:2022-05-25 11:44:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:02:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码