设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间07 现在时间07 缓存数据 时间很快,生活很慢,日子平凡里,不动声色,就很美好。

时间很快,生活很慢,日子平凡里,不动声色,就很美好。

查看: 1542|回复: 2

深入理解TCP协议与UDP协议的原理及区别

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:205
  • 打卡月天数:0
  • 打卡总奖励:3013
  • 最近打卡:2023-08-27 04:24:37
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
388
主题
361
精华
0
金钱
4155
积分
765
注册时间
2022-12-22
最后登录
2025-3-15

发表于 2023-3-1 15:27:22 | 显示全部楼层 |阅读模式
网络编程有三个要素,分别是IP地址、端口号和通信协议,那本文主要讲述的是TCP与UDP这两种通信协议,以及编程的实现。
首先,我们需要了解一下IP地址、端口号、通信协议的相关知识。

一、IP地址

网络中的计算机使用IP地址来进行唯一标识,IP地址有IPv4和IPv6两种类型。IPv4采用十进制或二进制表示形式,十进制是一种比较常用的表示形式,如
  1. 192.168.1.131
复制代码
,IPv6采用十六进制表示形式,一般不常用。
如何查看IP地址相关信息:
在Windows系统下,打开cmd,输入命令
  1. ipconfig
复制代码
,按回车即可查看。在Linux或Mac系统下,打开终端,使用
  1. ifconfig
复制代码
命令,按回车即可查看。

二、端口号

端口号是计算机中的应用程序的一个整数数字标号,用来区分不同的应用程序。
  1. 0 ~ 1024
复制代码
为被系统使用或保留的端口号,
  1. 0 ~ 65535
复制代码
为有效的端口号,也就是说我们要对一些程序定义端口号的时候,要选择
  1. 1024 ~ 65535
复制代码
范围内的整数数字。
比如,以前学过的MySQL的端口号是3306,SQLServer的端口号是1433,查了一下Oracle的端口号是1521。
一定要把这些数据库对应的端口号,藏在深深的脑海里,以后在连接数据库的时候,会使用到端口号。

三、通信协议

说的通俗一点,通信协议就是网络通信中的规则,分为TCP协议和UDP协议两种。
第一种:TCP协议
英文名:Transmission Control Protocol
中文名:传输控制协议
协议说明:TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
举例:打电话,需要双方都接通,才能进行对话
特点:效率低,数据传输比较安全
第二种:UDP协议
英文名:User Datagram Protocol
中文名:数据报协议
协议说明:UDP是一种面向无连接的传输层通信协议。
举例:发短信,不需要双方建立连接,But,数据报的大小应限制在64k以内
特点:效率高,数据传输不安全,容易丢包

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

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

162745mdvzr5nd5rrn5j9y.png

注:图中端口号、IP地址为演示,并非真实
2、OSI参考模型与TCP/IP参考模型

162745zclrxiijl2gc6qqj.png


五、TCP编程

TCP是基于字节流的传输层通信协议,所以TCP编程是基于IO流编程。
对于客户端,我们需要使用
  1. Socket
复制代码
类来创建对象。对于服务器端,我们需要使用
  1. ServerSocket
复制代码
来创建对象,通过对象调用
  1. accept()
复制代码
方法来进行监听是否有客户端访问。
客户端与服务器端图解:

162745js4j7sl7yljzib5y.png

客户端与服务器端实现步骤:
前提:创建一个项目,在项目中创建两个模块(model),一个模块用来放客户端相关代码,一个模块用来放服务器端相关代码。
目录结构如下图
162746zcid3di72qpypoy8.png

客户端:
1、创建
  1. Socket
复制代码
对象,并指定服务器端应用程序的端口号和服务器端主机的IP地址。
2、使用
  1. Socket
复制代码
的对象调用
  1. getOutputStream()
复制代码
方法来获取字节输出流对象。
3、调用字节输出流的
  1. write(byte[] buf)
复制代码
或者
  1. write(int b)
复制代码
向服务器发送指定数据。
4、记得关闭流。
服务器端:
1、创建
  1. ServerSocket
复制代码
对象,并指定该应用程序的端口号,端口号必须和客户端指定的端口号一样。
2、使用
  1. ServerSocket
复制代码
对象的
  1. accept()
复制代码
方法来监听客户端发送过来的请求,返回值为
  1. Socket
复制代码
对象。
3、调用
  1. Socket
复制代码
对象的
  1. getInputStream()
复制代码
方法获取字节输入流对象
4、调用字节输入流对象的
  1. read(byte[] buf)
复制代码
  1. read()
复制代码
方法获取数据。
5、记得关闭流。
实例:
客户端向服务器端发送信息,并显示在服务器端。
Client类(客户端)
  1. package cn.tkrnet.client;

  2. import java.io.IOException;
  3. import java.io.OutputStream;
  4. import java.net.Socket;

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

  17.         //关闭流
  18.         os.close();
  19.         client.close();
  20.     }
  21. }
复制代码
Server类(服务器端)
  1. package cn.tkrnet.server;

  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.net.ServerSocket;
  5. import java.net.Socket;

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

  9.         //创建ServerSocket对象,这里的端口号必须与客户端的端口号相同
  10.         ServerSocket server = new ServerSocket(9000);

  11.         //调用方法accept(),用来监听客户端发来的请求
  12.         Socket socket = server.accept();

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

  15.         //读取输入流中的数据
  16.         int b = 0;
  17.         while ((b =is.read()) != -1){
  18.             System.out.print((char)b);
  19.         }
  20.         //关闭流
  21.         is.close();
  22.         socket.close();
  23.         server.close();
  24.     }
  25. }
复制代码
提示:在运行程序时,一定要先运行服务器端的程序代码,再运行客户端的程序代码。因为客户端要向服务器发送请求,前提是服务器端要处于开启状态。
Server类(服务器端)运行结果:
  1. --服务器端已开启--
复制代码
Client类(客户端)运行结果:
  1. 信息已发送
复制代码
Client类(客户端)运行后,Server类(服务器端)收到信息,运行结果:
  1. --服务器端已开启--Java is my friend !
复制代码
实例分析:
服务器端启动后,服务器端的
  1. accept()
复制代码
方法一直处于监听状态,直到客户端连接了服务器,服务器端再从流中读取客户端发来的数据。
恕我直言,这是一个超级无敌简单的单向通信实例。

六、UDP编程

UDP使用数据报进行数据传输,没有客户端与服务器端之分,只有发送方与接收方,两者哪个先启动都不会报错,但是会出现数据丢包现象。发送的内容有字数限制,大小必须限制在64k以内。
发送方与接收方实现步骤:
前提:创建一个项目,在项目中创建两个模块(model),一个模块用来放发送方相关代码,一个模块用来放接收方相关代码。
目录结构如下图
162746adidmrni408acci2.png

发送方:
1、创建
  1. DatagramSocket
复制代码
对象,可以指定应用程序的端口号,也可以不指定。
2、准备需要发送的数据
3、创建
  1. DatagramPacket
复制代码
对象,用来对发送的数据进行打包,需要指定发送内容、发送多少、发送到哪里和接收方的端口号四个参数。
4、调用
  1. DatagramSocket
复制代码
对象的
  1. send()
复制代码
方法发送数据。
5、记得关闭流。
接收方:
1、创建
  1. DatagramSocket
复制代码
对象,指定接收方的端口号,这个必须指定。
2、创建一个
  1. byte
复制代码
类型数组,用来接收发送方发送过来的数据。
3、创建
  1. DatagramPacket
复制代码
对象,准备接收数据。
4、调用
  1. DatagramSocket
复制代码
对象的
  1. receive()
复制代码
方法用于接收数据。
5、使用
  1. String
复制代码
类的构造方法将
  1. byte
复制代码
类型的数组中的数据转化成
  1. String
复制代码
类型并显示。
6、记得关闭流。
实例:
发送方发送信息,接收方接收信息,并显示。
Sender类(发送方)
  1. package cn.tkrnet.Sender;

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

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

  6.         //创建接受或发送的数据报套接字,并指定发送方的端口号为7770
  7.         DatagramSocket ds = new DatagramSocket(7770);   //端口号也可以不指定
  8.         System.out.println("---发送方---");

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

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

  13.         ds.send(dp);    //发送数据报
  14.         System.out.println("数据已发送");
  15.         //关闭流
  16.         ds.close();
  17.     }
  18. }
复制代码
Receiver类(接收方)
  1. package cn.tkrnet.receiver;

  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;

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

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

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

  14.         //接收数据
  15.         ds.receive(dp);
  16.         System.out.println(new String(b,0,dp.getLength()));
  17.         //关闭流
  18.         ds.close();
  19.     }
  20. }
复制代码
提示:在运行程序时,先运行发送方程序,还是先运行接收方程序都不会报错,但是有可能会出现数据丢包,一般我们都先运行接收方的程序代码,再运行发送方的程序代码。
Receiver类(接收方)运行结果:
  1. ---接收方---
复制代码
Sender类(发送方)运行结果:
  1. ---发送方---数据已发送
复制代码
Sender类(发送方)运行后,Receiver类(接收方)接收到信息,运行结果:
  1. ---接收方---Java is my friend !
复制代码
实例分析:
只有接收方先启动运行,才会存在端口号为7788的程序,发送方才能发送数据到指定端口号7788,接收方才能接收数据。
不瞒你说,这也是个超级无敌简单的单向通信实例。

七、总结

到此这篇关于深入理解TCP协议与UDP协议的原理及区别的文章就介绍到这了,更多相关TCP协议与UDP协议内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
21
积分
22
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2024-11-25 14:22:06 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
18
积分
16
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2025-4-20 14:49:51 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表