当前位置: 首页 > news >正文

网络编程(TCP协议,UDP协议)

目录

网络编程三要素

IP

IPv4

InetAddress类

端口号

协议

UDP协议

UDP协议发送数据

UDP协议接收数据

UDP的三种通信方式(代码实现)

TCP协议

TCP通信程序

三次握手和四次挥手 

练习 

1、客户端:多次发送数据服务器:接收多次接收数据,并打印

2、客户端:发送一条数据,接收服务端反馈的消息并打印

服务器:接收数据并打印,再给客户端反馈消息

3、客户端:将本地文件上传到服务器。接收服务器的反馈。服务器:接收客户端上传的文件,上传完毕之后给出反馈。



什么是网络编程?

在网络通信协议下,不同计算机上运行的程序,进行的数据传输。

常见软件架构有哪些?

CS/BS

通信的软件架构CS\BS的各有什么区别和优缺点

CS:客户端服务端模式需要开发客户端

BS:浏览器服务端模式不需要开发客户端,

CS:适合定制专业化的办公类软件如:IDEA、网游

BS:适合移动互联网应用,可以在任何地方随时访问的系统


C/S(Client/Server)架构是一种分布式计算模型,其中客户端和服务器分别承担不同的功能和责任。客户端是面向用户的界面和应用程序,负责向用户提供交互界面和功能。服务器则负责处理客户端发送的请求,进行数据处理和存储,并将处理结果返回给客户端。

B/S(Browser/Server)架构也是一种分布式计算模型,类似于c/s架构。不同之处在于,b/s架构中的客户端是基于浏览器的Web应用程序,通过浏览器访问Web服务器上的应用程序。服务器处理客户端请求,并将结果通过Web页面返回给客户端。

总体而言,c/s架构适用于需要实现复杂业务逻辑和功能的应用程序,而b/s架构适用于面向广大用户的Web应用程序。

网络编程三要素

IP:设备在网络中的地址,是唯一的标识。

端口号:应用程序在设备中唯一的标识。

协议:数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。

IP

全称:Internet Protocol,是互联网协议地址,也称IP地址。
是分配给上网设备的数字标签。

常见的IP分类为:IPv4、IPv6

IPv4

全称:Internet Protocol version4,互联网通信协议第四版

采用32位地址长度,分成4组

网际协议版本4(IPv4)是互联网通信中应用最广泛的网络协议之一,它负责将数据包从源头发送到目的地。IPv4使用32位地址格式,能够提供约43亿个独立的地址。这些地址被用于在互联网上唯一标识每个网络设备,如计算机、手机或其他终端设备。

IPv4的核心功能包括无连接的数据传输和最大努力交付。无连接意味着在数据传输之前,不需要建立持久的连接状态。每个数据包都是独立处理并路由至目标地址。最大努力交付则表明该协议尽力将数据包传送到目的地,但不保证所有数据包均能成功到达,也不保证它们会按顺序到达。这些特性需要由更高层的协议,如传输控制协议(TCP),来加以管理和修正。

IPv4的设计和结构对其普及和功能至关重要。IPv4数据包包含一个固定长度的头部,通常为20字节,后面可跟随可选的扩展部分。固定头部包括多个字段,如版本号、首部长度、总长度、标识、标志、片偏移、生存时间(TTL)、协议、首部校验和、源地址和目的地址等。这些字段共同确保了数据包的正确传输及其优先级、路由和错误校验。

由于IPv4地址的枯竭问题,互联网社区早在1990年代就开始研究替代方案。最终,网际协议版本6(IPv6)被开发出来,以解决地址空间不足的问题。IPv6使用128位地址格式,可以提供近乎无限的地址空间。尽管IPv6在技术上解决了IPv4的许多限制,但由于技术升级和迁移的复杂性,IPv6的普及速度相对较慢。

总结来说,IPv4作为互联网的基础协议,虽然存在一些限制,但它在过去几十年里成功地支撑了互联网的迅猛发展。然而,随着IPv4地址的耗尽和互联网需求的不断增长,向IPv6的过渡已成为不可逆转的趋势。未来,IPv6可能会完全取代IPv4,成为互联网通信的主流协议。

InetAddress类

static InetAddress getByName(string host)        确定主机名称的IP地址,主机名称可以是机器名称,也可以是IP地址
String getHostName()        获取此IP地址的主机名
String getHostAddress()        返回文本显示中的IP地址字符串

package InetAddress24_6_21;import java.net.InetAddress;
import java.net.UnknownHostException;public class InetAddressDemo1 {public static void main(String[] args) throws UnknownHostException {//1.获取InetAddress的对象// IP的对象 一台电脑的对象InetAddress address=InetAddress.getByName("努力敲代码的小火龙");System.out.println(address);String name = address.getHostName();System.out.println(name);String ip = address.getHostAddress();System.out.println(ip);}
}

端口号

应用程序在设备中唯一的标识。

端口号:由两个字节表示的整数,取值范围:0~65535

其中0~1023之间的端口号用于一些知名的网络服务或者应用。

我们自己使用1024以上的端口号就可以了。

注意:一个端口号只能被一个应用程序使用,

协议

计算机网络中,连接和通信的规则被称为网络通信协议

OSI参考模型和TCP/IP参考模型是网络通信中常用的两种参考模型,用于描述计算机网络中不同层次的协议和功能。两种参考模型的各层对应的协议如下:

OSI参考模型的七层对应协议:
1. 物理层:主要负责传输比特流,按照电气、光学或者机械方式传送信号。没有具体的协议对应。
2. 数据链路层:主要负责将比特流分成具有特定意义的帧,并进行错误检测和纠正。常用的协议有以太网(Ethernet)和无线局域网(Wi-Fi)。
3. 网络层:主要负责将数据包从源主机传输到目标主机,包括寻址、路由选择和包分片等功能。常用的协议有Internet协议(IP)。
4. 传输层:主要负责提供端到端的可靠数据传输,包括流量控制和拥塞控制等功能。常用的协议有传输控制协议(TCP)和用户数据报协议(UDP)。
5. 会话层:主要负责建立、管理和终止应用程序之间的通信会话。没有具体的协议对应。
6. 表示层:主要负责处理数据的表示和转换,确保不同主机上的应用程序能够解释和理解数据的意义。没有具体的协议对应。
7. 应用层:最上层的应用程序直接面向用户,并提供特定的网络服务,例如电子邮件(SMTP)、文件传输(FTP)和域名系统(DNS)等。

TCP/IP参考模型的四层对应协议:
1. 网络接口层(网络接入层):主要负责将数据链路层的帧封装为IP数据包,并进行物理传输。常用的协议有以太网(Ethernet)和无线局域网(Wi-Fi)。
2. 网际层(互联网层):主要负责将数据包从源主机传输到目标主机,包括寻址、路由选择和包分片等功能。常用的协议有Internet协议(IP)。
3. 传输层:主要负责提供端到端的可靠数据传输,包括流量控制和拥塞控制等功能。常用的协议有传输控制协议(TCP)和用户数据报协议(UDP)。
4. 应用层:最上层的应用程序直接面向用户,并提供特定的网络服务,例如电子邮件(SMTP)、文件传输(FTP)和域名系统(DNS)等。

需要注意的是,TCP/IP参考模型的网络接口层对应了OSI参考模型的物理层和数据链路层。因此,TCP/IP参考模型只有四层,而OSI参考模型有七层。

UDP协议

用户数据报协议(User Datagram Protocol)
UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据

UDP协议发送数据

package UDPDemo;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SendMessageDemo {public static void main(String[] args) throws IOException {//发送数据//创建Datagramsocket对象//绑定端口,以后我们就是通过这个端口往外发送// 空参:所有可用的端口中随机一个进行使用// 有参:指定端口号进行绑定DatagramSocket ds=new DatagramSocket();//打包数据String str="hello world";byte[] bytes=str.getBytes();InetAddress address=InetAddress.getByName("127.0.0.1");int port=10086;//数据打包DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);//发送数据ds.send(dp);//释放资源ds.close();}
}

UDP协议接收数据

package UDPDemo;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class ReceiveMessageDemo {public static void main(String[] args) throws IOException {//1.创建Datagramsocket对象(快递公司)//在接收的时候,一定要绑定端口//而且绑定的端口一定要跟发送的端口保持一致DatagramSocket ds=new DatagramSocket(10086);//接收数据包byte[] bytes=new byte[1024];DatagramPacket dp=new DatagramPacket(bytes,bytes.length);//该方法是阻塞的,程序执行到这一步的时候,会在这里死等,等发送端发送消息ds.receive(dp);//解析数据包byte[] data=dp.getData();int len=dp.getLength();InetAddress address=dp.getAddress();int port=dp.getPort();System.out.println("接收到数据"+new String(data,0,len));System.out.println("这个数据是从"+address+"这台电脑中的"+port+"这个端口发出的");//释放资源ds.close();}
}

先运行接收端,再运行发送端 

UDP的三种通信方式(代码实现)

单播

  • 之前的代码就是单播

组播

  • 组播地址:224.0.0.0~239.255.255.255
  • 其中224.0.0.0~224.0.0.255 为预留的组播地址

三个接收端: 

package UDPDemo2;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;public class ReceiveMessageDemo3 {public static void main(String[] args) throws IOException {MulticastSocket ms=new MulticastSocket(10000);//将当前本机,添加到224.0.0.1的这一组当中InetAddress address=InetAddress.getByName("224.0.0.1");ms.joinGroup(address);//接收数据包byte[] bytes=new byte[1024];DatagramPacket dp=new DatagramPacket(bytes,bytes.length);ms.receive(dp);//解析数据包byte[] data=dp.getData();int len=dp.getLength();int port=dp.getPort();System.out.println("这个数据是从"+address+"这台电脑中的"+port+"这个端口发出的,发出的数据为"+new String(data,0,len));//释放资源ms.close();}
}

 发送端

package UDPDemo2;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;public class SendMessageDemo {public static void main(String[] args) throws IOException {MulticastSocket ms=new MulticastSocket();//打包数据String str="hello world";byte[] bytes=str.getBytes();InetAddress address=InetAddress.getByName("224.0.0.1");int port=10000;//数据打包DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);//发送数据ms.send(dp);//释放资源ms.close();}
}

 

广播 

  • 广播地址:255.255.255.255 
package UDPDemo;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SendMessageDemo {public static void main(String[] args) throws IOException {//发送数据//创建Datagramsocket对象//绑定端口,以后我们就是通过这个端口往外发送// 空参:所有可用的端口中随机一个进行使用// 有参:指定端口号进行绑定DatagramSocket ds=new DatagramSocket();//打包数据String str="hello world";byte[] bytes=str.getBytes();InetAddress address=InetAddress.getByName("255.255.255.255");int port=10086;//数据打包DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);//发送数据ds.send(dp);//释放资源ds.close();}
}

 

TCP协议

传输控制协议TCP(Transmission Control Protocol)

TCP协议是面向连接的通信协议。

速度慢,没有大小限制,数据安全。

TCP通信程序

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象通信之前要保证连接已经建立
通过Socket产生I0流来进行网络通信

客户端

  • 创建客户端的Socket对象(Socket)与指定服务端连接   Socket(string host,int port)
  • 获取输出流,写数据   Outputstream getoutputstream()
  • 释放资源
package TCPDemo;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {//创建Socket对象// 在创建对象的同时会连接服务端,如果连接不上,代码会报错Socket socket=new Socket("127.0.0.1",10001);//可以从连接通道中获取输出流OutputStream os=socket.getOutputStream();//写出数据os.write("你好你好".getBytes());//释放资源os.close();socket.close();}
}

 服务器

  • 创建服务器端的Socket对象(ServerSocket)        ServerSocket(int port)
  • 监听客户端连接,返回一个Socket对象   Socket accept()
  • 获取输入流,读数据,并把数据显示在控制台   InputStream getInputstream()
  • 释放资源    void close()
package TCPDemo;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {//创建对象ServerSockerServerSocket ss=new ServerSocket(10001);//监听客户端的链接Socket socket=ss.accept();//从连接通道中获取输入流读取数据InputStream is=socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);int b;while ((b=isr.read())!=-1){System.out.println((char)b);}//释放资源socket.close();ss.close();}
}

三次握手和四次挥手 

三次握手(Three-way Handshake)和四次挥手(Four-way Fin-Wait-RST)是TCP协议中建立和终止连接的过程。

1. 三次握手

三次握手是指在TCP连接建立过程中,客户端和服务器端需要进行三次报文交换,以确保双方的发送和接收能力都正常。具体过程如下:

a) 客户端向服务器端发送一个带有SYN标志的报文,表示请求建立连接。

b) 服务器端收到客户端的SYN报文后,会回复一个带有SYN和ACK标志的报文,表示同意建立连接。

c) 客户端收到服务器端的SYN+ACK报文后,会回复一个带有ACK标志的报文,表示连接已建立。

2. 四次挥手

四次挥手是指在TCP连接终止过程中,客户端和服务器端需要进行四次报文交换,以确保双方的数据都已经被对方接收并处理完毕。具体过程如下:

a) 客户端向服务器端发送一个带有FIN标志的报文,表示请求终止连接。

b) 服务器端收到客户端的FIN报文后,会回复一个带有ACK标志的报文,表示已经收到了客户端的终止请求。

c) 服务器端在处理完所有数据后,向客户端发送一个带有FIN标志的报文,表示同意终止连接。

d) 客户端收到服务器端的FIN报文后,会回复一个带有ACK标志的报文,表示连接已终止。

练习 

1、客户端:多次发送数据
服务器:接收多次接收数据,并打印

客户端

package Test1;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class Client {public static void main(String[] args) throws IOException {Socket socket=new Socket("127.0.0.1",10001);Scanner sc=new Scanner(System.in);OutputStream os=socket.getOutputStream();while (true){System.out.println("请输入数据");String str=sc.nextLine();//退出方法if("886".equals(str)){break;}//写出数据os.write(str.getBytes());}//释放资源}
}

 服务器

package Test1;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket ss=new ServerSocket(10001);//等待客户端来连接Socket socket = ss.accept();//读取数据InputStream is=socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);int b;while ((b=isr.read())!=-1){System.out.print((char) b);}//释放资源socket.close();ss.close();}
}

2、客户端:发送一条数据,接收服务端反馈的消息并打印

服务器:接收数据并打印,再给客户端反馈消息

客户端

package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {Socket socket=new Socket("127.0.0.1",10001);//写出数据String str="你好呀";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//写出结束标记socket.shutdownOutput();//接收服务端的回写数据InputStream is=socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);int b;while ((b=isr.read())!=-1){System.out.print((char) b);}//释放资源socket.close();}
}

服务端

package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket ss=new ServerSocket(10001);//等待客户端链接Socket socket = ss.accept();//从socket中获取输入流读取数据InputStream is = socket.getInputStream();InputStreamReader isr=new InputStreamReader(is);int b;while ((b=isr.read())!=-1){System.out.print((char)b);}//回写数据String str="hello";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//释放资源socket.close();ss.close();}
}

3、客户端:将本地文件上传到服务器。接收服务器的反馈。
服务器:接收客户端上传的文件,上传完毕之后给出反馈。

客户端

package Test3;import java.io.*;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {Socket socket=new Socket("127.0.0.1",10001);//读取本地文件中的数据,并写到服务器当中BufferedInputStream bis=new BufferedInputStream(new FileInputStream("E:\\java\\net\\clientdir\\a.jpg"));BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());byte[] bytes=new byte[1024];int len;while ((len=bis.read(bytes))!=-1){bos.write(bytes,0,len);}bos.flush();//往服务器写出的结束标记socket.shutdownOutput();//接收服务器的回写数据BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));String line = br.readLine();System.out.println(line);//释放资源socket.close();}
}

 服务端

package Test3;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket ss=new ServerSocket(10001);//等待客户端链接Socket socket = ss.accept();//读取数据并保存到本地文件中BufferedInputStream bis=new BufferedInputStream(socket.getInputStream());BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("E:\\java\\net\\serverdir\\a.jpg"));int len;byte[] bytes=new byte[1024];while ((len=bis.read())!=-1){bos.write(bytes,0,len);}bos.flush();//回写数据BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bw.write("上传成功");bw.newLine();bw.flush();//释放资源socket.close();ss.close();}
}

这一期就到这里啦

努力遇见更好的自己!!!

相关文章:

  • tron-passwd写入提权
  • 音视频开发—FFmpeg 打开摄像头进行RTMP推流
  • SSLyze:一款快速高效的SSLTLS扫描工具
  • 2024年全球架构师峰会(ArchSummit深圳站)
  • 大型语言模型在AMD GPU上的推理优化
  • 使用阿里开源的Spring Cloud Alibaba AI开发第一个大模型应用
  • 探索Python元类的奥秘及其应用场景
  • 【Python爬虫】爬取名人名言页面并进行简单的数据清洗(入门级)
  • C# 中的隐式和显式类型转换
  • 华为HCIP Datacom H12-821 卷9
  • django学习入门系列之第三点《CSS基础样式介绍2》
  • select实现超时保护机制
  • 【性能优化】表分桶实践最佳案例
  • odoo17 小变更3 Warning、 “attrs “和 “states “不再用
  • 树和二叉树的定义
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • iOS小技巧之UIImagePickerController实现头像选择
  • Javascript弹出层-初探
  • leetcode386. Lexicographical Numbers
  • Linux CTF 逆向入门
  • Linux下的乱码问题
  • node学习系列之简单文件上传
  • SpringBoot 实战 (三) | 配置文件详解
  • STAR法则
  • 安装python包到指定虚拟环境
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 日剧·日综资源集合(建议收藏)
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 世界上最简单的无等待算法(getAndIncrement)
  • 用 Swift 编写面向协议的视图
  • 终端用户监控:真实用户监控还是模拟监控?
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • postgresql行列转换函数
  • ​Redis 实现计数器和限速器的
  • (003)SlickEdit Unity的补全
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (SpringBoot)第七章:SpringBoot日志文件
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (论文阅读40-45)图像描述1
  • (一)appium-desktop定位元素原理
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)Unity3DUnity3D在android下调试
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET Core引入性能分析引导优化
  • .net mvc 获取url中controller和action
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET6实现破解Modbus poll点表配置文件
  • .net连接MySQL的方法
  • [1] 平面(Plane)图形的生成算法