乐趣区

关于java:终于把-TCP-与-UDP-协议整明白了

网络编程有三个因素,别离是 IP 地址、端口号和通信协议,那本文次要讲述的是 TCP 与 UDP 这两种通信协议,以及编程的实现。

首先,咱们须要理解一下 IP 地址、端口号、通信协议的相干常识。

一、IP 地址

网络中的计算机应用 IP 地址来进行惟一标识,IP 地址有 IPv4 和 IPv6 两种类型。IPv4 采纳十进制或二进制示意模式,十进制是一种比拟罕用的示意模式,如192.168.1.131,IPv6 采纳十六进制示意模式,个别不罕用。

如何查看 IP 地址相干信息:

在 Windows 零碎下,关上 cmd,输出命令 ipconfig,按回车即可查看。在 Linux 或 Mac 零碎下,关上终端,应用ifconfig 命令,按回车即可查看。

二、端口号

端口号是计算机中的应用程序的一个整数数字标号,用来辨别不同的应用程序。

0 ~ 1024 为被零碎应用或保留的端口号,0 ~ 65535为无效的端口号,也就是说咱们要对一些程序定义端口号的时候,要抉择 1024 ~ 65535 范畴内的整数数字。

比方,以前学过的 MySQL 的端口号是 3306,SQLServer 的端口号是 1433,查了一下 Oracle 的端口号是 1521。

肯定要把这些数据库对应的端口号,藏在深深的脑海里,当前在连贯数据库的时候,会应用到端口号。

三、通信协议

说的艰深一点,通信协议就是网络通信中的规定,分为 TCP 协定和 UDP 协定两种。

第一种:TCP 协定

英文名:Transmission Control Protocol 中文名:传输控制协议 协定阐明:TCP 是一种面向连贯的、牢靠的、基于字节流的传输层通信协议。

举例:打电话,须要单方都接通,能力进行对话

特点:效率低,数据传输比拟平安

第二种:UDP 协定

英文名:User Datagram Protocol 中文名:数据报协定 协定阐明:UDP 是一种面向无连贯的传输层通信协议。

举例:发短信,不须要单方建设连贯,But,数据报的大小应限度在 64k 以内

特点:效率高,数据传输不平安,容易丢包

四、三要素关系图与网络模型图

1、网络编程三要素关系图

注:图中端口号、IP 地址为演示,并非实在

2、OSI 参考模型与 TCP/IP 参考模型

五、TCP 编程

TCP 是基于字节流的传输层通信协议,所以 TCP 编程是基于 IO 流编程。

对于客户端,咱们须要应用 Socket 类来创建对象。对于服务器端,咱们须要应用 ServerSocket 来创建对象,通过对象调用 accept() 办法来进行监听是否有客户端拜访。

客户端与服务器端图解:

客户端与服务器端实现步骤:

前提:创立一个我的项目,在我的项目中创立两个模块(model),一个模块用来放客户端相干代码,一个模块用来放服务器端相干代码。

目录构造如下图

客户端

1、创立 Socket 对象,并指定服务器端应用程序的端口号和服务器端主机的 IP 地址。

2、应用 Socket 的对象调用 getOutputStream() 办法来获取字节输入流对象。

3、调用字节输入流的 write(byte[] buf) 或者 write(int b) 向服务器发送指定数据。

4、记得敞开流。

服务器端

1、创立 ServerSocket 对象,并指定该应用程序的端口号,端口号必须和客户端指定的端口号一样。

2、应用 ServerSocket 对象的 accept() 办法来监听客户端发送过去的申请,返回值为 Socket 对象。

3、调用 Socket 对象的 getInputStream() 办法获取字节输出流对象

4、调用字节输出流对象的 read(byte[] buf)read()办法获取数据。

5、记得敞开流。

实例

客户端向服务器端发送信息,并显示在服务器端。

Client 类(客户端)

package cn.tkrnet.client;

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

public class Client {public static void main(String[] args) throws IOException {
        
        // 创立 Socket 对象,指定要发送到服务器端的 IP 地址,以及服务器端应用程序接管的端口号
        //localhost 代表本机 IP 地址
        Socket client = new Socket("localhost",9000);
        
        // 获取输入流,用于向服务器端发送数据
        OutputStream os = client.getOutputStream();
        
        os.write("Java is my friend !".getBytes());
        System.out.println("信息已发送");

        // 敞开流
        os.close();
        client.close();}
}

Server 类(服务器端)

package cn.tkrnet.server;

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

public class Server {public static void main(String[] args) throws IOException {System.out.println("-- 服务器端已开启 --");

        // 创立 ServerSocket 对象,这里的端口号必须与客户端的端口号雷同
        ServerSocket server = new ServerSocket(9000);

        // 调用办法 accept(),用来监听客户端发来的申请
        Socket socket = server.accept();

        // 获取输出流对象
        InputStream is = socket.getInputStream();

        // 读取输出流中的数据
        int b = 0;
        while ((b =is.read()) != -1){System.out.print((char)b);
        }
        // 敞开流
        is.close();
        socket.close();
        server.close();}
}

提醒:在运行程序时,肯定要先运行服务器端的程序代码,再运行客户端的程序代码。因为客户端要向服务器发送申请,前提是服务器端要处于开启状态。

Server 类(服务器端)运行后果:

-- 服务器端已开启 --

Client 类(客户端)运行后果:

信息已发送

Client 类(客户端)运行后,Server 类(服务器端)收到信息,运行后果:

-- 服务器端已开启 --
Java is my friend !

实例剖析:

服务器端启动后,服务器端的 accept() 办法始终处于监听状态,直到客户端连贯了服务器,服务器端再从流中读取客户端发来的数据。

恕我直言,这是一个超级无敌简略的单向通信实例。

六、UDP 编程

UDP 应用数据报进行数据传输,没有客户端与服务器端之分,只有发送方与接管方,两者哪个先启动都不会报错,然而会呈现数据丢包景象。发送的内容有字数限度,大小必须限度在 64k 以内。

发送方与接管方实现步骤:

前提:创立一个我的项目,在我的项目中创立两个模块(model),一个模块用来放发送方相干代码,一个模块用来放接管方相干代码。

目录构造如下图

发送方

1、创立 DatagramSocket 对象,能够指定应用程序的端口号,也能够不指定。

2、筹备须要发送的数据

3、创立 DatagramPacket 对象,用来对发送的数据进行打包,须要指定发送内容、发送多少、发送到哪里和接管方的端口号四个参数。

4、调用 DatagramSocket 对象的 send() 办法发送数据。

5、记得敞开流。

接管方

1、创立 DatagramSocket 对象,指定接管方的端口号,这个必须指定。

2、创立一个 byte 类型数组,用来接管发送方发送过去的数据。

3、创立 DatagramPacket 对象,筹备接收数据。

4、调用 DatagramSocket 对象的 receive() 办法用于接收数据。

5、应用 String 类的构造方法将 byte 类型 的数组中的数据转化成 String 类型并显示。

6、记得敞开流。

实例

发送方发送信息,接管方接管信息,并显示。

Sender 类(发送方)

package cn.tkrnet.Sender;

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

public class Sender {public static void main(String[] args) throws IOException {

        // 创立承受或发送的数据报套接字,并指定发送方的端口号为 7770
        DatagramSocket ds = new DatagramSocket(7770);   // 端口号也能够不指定
        System.out.println("--- 发送方 ---");

        // 创立数据报对象,用来发送数据
        byte[] b = "Java is my friend!".getBytes();

        //8800 为接管方的端口号,netAddress.getByName("localhost")是获取主机的 IP 地址
        DatagramPacket dp = new DatagramPacket(b,b.length, InetAddress.getByName("localhost"),7788);

        ds.send(dp);    // 发送数据报
        System.out.println("数据已发送");
        // 敞开流
        ds.close();}
}

Receiver 类(接管方)

package cn.tkrnet.receiver;

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

public class Receiver {public static void main(String[] args) throws IOException {System.out.println("--- 接管方 ---");

        // 创立数据报套接字对象,指定的端口号要和发送方发送数据的端口号雷同
        //(不是发送方的端口号 7770,是发送方发送数据的端口号 7788)DatagramSocket ds = new DatagramSocket(7788);

        // 创立接收数据报的对象
        byte[] b = new byte[1024];
        DatagramPacket dp = new DatagramPacket(b,b.length);

        // 接收数据
        ds.receive(dp);
        System.out.println(new String(b,0,dp.getLength()));
        // 敞开流
        ds.close();}
}

提醒:在运行程序时,先运行发送方程序,还是先运行接管方程序都不会报错,然而有可能会呈现数据丢包,个别咱们都先运行接管方的程序代码,再运行发送方的程序代码。

Receiver 类(接管方)运行后果:

--- 接管方 ---

Sender 类(发送方)运行后果:

--- 发送方 ---
数据已发送

Sender 类(发送方)运行后,Receiver 类(接管方)接管到信息,运行后果:

    --- 接管方 ---
    Java is my friend!

实例剖析:

只有接管方先启动运行,才会存在端口号为 7788 的程序,发送刚才能发送数据到指定端口号 7788,接管刚才能接收数据。

不瞒你说,这也是个超级无敌简略的单向通信实例。

七、总结

以上是我分享给大家的对于网络通信 TCP 协定与 UDP 协定的一些总结。

如果感觉还不错的话,就点个赞和在看吧!

原文链接:https://blog.csdn.net/m0_4789…

版权申明:本文为 CSDN 博主「酷酷的猿」的原创文章,遵循 CC 4.0 BY-SA 版权协定,转载请附上原文出处链接及本申明。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版