JAVA网络编程(一)

news/2024/11/16 20:43:57/

一、什么是网络编程

定义:在网络通信协议下,不同计算机上运行的程序,进行的数据传输。
应用场景:即时通信,网游,邮件等
不管什么场景,都是计算机与计算机之间通过网络在进行数据传输
java提供一个java.net包,可以帮助我们开发网络应用程序。

二、常见的网络应用程序架构

在这里插入图片描述
CS架构是指在远端有一个服务器Server,用户需要在本地下载一个客户端Client。
BS架构是指远端有一个服务器,用户通过浏览器进行访问。
在这里插入图片描述

BS架构的优缺点

优点:
①不需要开发客户端,只需要页面和服务端
②用户不需要下载应用,只需要在浏览器访问
缺点:
①如果应用中的资源体积过大,那么用户体验将受到影响,比如图片过大,浏览器就要加载一会儿才能显示。
在这里插入图片描述

CS架构的优缺点

优点:
①画面可以做的非常精美,不用担心传输慢,因为需要提前下载资源包到本地
缺点:
②需要开发客户端和服务端,工作量加大
③用户需要下载安装和更新

三、网络编程三要素

IP、端口号、协议
在这里插入图片描述

IP

全称:Internet Protocol,是互联网协议地址,也称ip地址,是分配给上网设备的数字标签。
常见的IP分类有IPv4和IPv6两种。

IPv4

在这里插入图片描述

IPv6

在这里插入图片描述

总结:

在这里插入图片描述

在这里插入图片描述

IPv4是如何节约分配的?

在这里插入图片描述
以网吧举例,网吧里面的电脑很多,不可能为每一台电脑设置一个公网ip,所以就出现了下面的方案:
所有电脑共用一个公网ip,每台电脑拥有一个局域网ip
在这里插入图片描述

特殊的Ip地址

127.0.0.1,也可以是localhost:是回送地址,也称本地回环地址,也称本机ip,永远只会寻找当前所在本机。
提问:
如果192.168.1.100是我电脑的ip地址,那么这个ip和127.0.0.1是一样的吗?
答案:不是的,192.168.1.100是局域网给你的电脑分配的ip地址,而127.0.0.1是只代表本机的地址
举例
使用电脑向192.168.1.100发送消息,数据会先经过路由器,然后通过路由器发送数据给我的电脑。
并且如果我的电脑换了一个局域网环境,比如换了一个路由器,那么我的电脑的ip地址可能会发生改变。
在这里插入图片描述
如果使用127.0.0.1,我的电脑就不会向路由器发送信息,信息在通过网卡的时候就会发现这条数据是发送给回环地址的,直接发送给我的电脑。
在这里插入图片描述

常见的cmd命令

在这里插入图片描述

总结

在这里插入图片描述

InetAddress对象

InetAddress类没有公有的构造方法,只能通过getByName(String name)方法获取InetAddress对象。
InetAddress对象表示一个IP,一个IP对应着一台网络中的设备,所以InetAddress对象也可以表示一台设备。
当获取到这台设备的InetAddress对象时,就可以给这个对象发送消息了

/*** @author Watching* * @date 2023/5/26* * Describe:* static InetAddress getByName(String host) 确定主机名称的ip地址,主机名称可以是机器名称,也可以是ip地址* String getHostName() 获取此ip地址的主机名* String getHostAddress() 返回文本显示中的ip地址字符串*/
public class MyInetAddressDemo1 {public static void main(String[] args) throws UnknownHostException {//InetAddress 表示ip的对象,而ip有表示一台联网设备,所以这也能表示一台设备对象InetAddress address = InetAddress.getByName("DESKTOP-DHVQ061");System.out.println(address);String hostAddress = address.getHostAddress();System.out.println(hostAddress);String hostName = address.getHostName();System.out.println(hostName);}
}

在这里插入图片描述

端口号

端口号时应用程序在一台设备中的唯一标识
端口号:由两个字节表示的整数,取值范围:0~65535
其中0~1023之间的端口用于一些知名的网络服务或应用,所以我们自己的程序应该使用1024以上的端口号
一个端口号只能被一个应用程序使用

协议

计算机网络中,连接和通信的规则被称为网络通信协议。
在这里插入图片描述

OSI参考模型
数据从应用层一直传输到物理层,转为可网络传递的二进制形式,传递另外一台电脑上,再由下到上到应用层,转为原始数据。
在这里插入图片描述
TCP/IP协议
TCP/IP模型将应用层、表示层、会话层合为一层,数据链路层、物理层合为一层。
TCP/IP模型减少了流程复杂度,减少了资源消耗
在这里插入图片描述
我们重点学习传输层的TCP和UDP协议。

UDP协议

UDP协议的特点就是速度快,面向无连接, 不管是否连接成功,都会发送数据,应用场景比如视频聊天,电话等,就算出现了连接失败,也只是会出现卡顿的情况
在这里插入图片描述

测试UDP传输数据

步骤:
1.创建DatagramSocket对象,建立连接
2.打包数据,需要指定接收端口
3.发送数据
4.关闭连接

/*** @author Watching* * @date 2023/5/26* * Describe:*/
public class SendMessageDemo1 {public static void main(String[] args) throws IOException {//发送数据//1.创建DatagramSocket对象//细节://绑定端口,以后我们就是通过这个端口往外发送//空参:所有可用的端口中随机一个进行使用//有参:指定端口号进行绑定DatagramSocket datagramSocket = new DatagramSocket();//2.打包数据String str = "你好威啊";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("127.0.0.1");int port = 10086;DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);//3.发送数据datagramSocket.send(dp);//4.关闭连接datagramSocket.close();}
}

在打包数据的时候,DatagramPacket里面有很多构造器,可以根据需要选择不同的构造器。

在这里插入图片描述

测试UDP接收数据

步骤:
1.创建DatagramSocket对象建立连接,端口要与发送者的目的端口一致
2.创建DatagramPacket对象接收数据
3.通过DatagramPacket对象获取数据数据长度发送者IP发送者端口号等信息
4.断开连接

/*** @author Watching* * @date 2023/5/27* * Describe:*/
public class ReceiveMessageDemo {public static void main(String[] args) throws IOException {//1.创建socket连接,端口要与发送消息的要相同DatagramSocket ds = new DatagramSocket(10086);//2.接受数据包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);//该方法是阻塞式的方法,会一直阻塞直到接受到消息ds.receive(dp);//3.解析数据包byte[] data = dp.getData();int length = dp.getLength();InetAddress address = dp.getAddress();int port = dp.getPort();System.out.println(new String(data,0, length));System.out.println("数据是从 [" + address + "]" + "发送来的");System.out.println("端口是 [" + port + "]");}
}

接收数据时使用的DatagramSocket对象的 receive(DatagramPacket dp) 方法,这个方法是阻塞式的,直到接收到传来的消息才会停止阻塞。

UDP的三种通信方式

单播
单对单传输
在这里插入图片描述
组播
一组设备接收消息
在这里插入图片描述
广播
所有设备都能接收消息
在这里插入图片描述

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

在这里插入图片描述

单播

前面我们编写的代码就是单播

组播

发送端:
步骤:
①创建组播连接,使用MultiCastSocket类
②创建DatagramPacket对象打包数据,需要指定接收端口
③发送消息
④关闭连接

/*** @author Watching* * @date 2023/5/27* * Describe:测试组播发送代码**/
public class SendMessageDemo2 {public static void main(String[] args) throws IOException {//1.创建组播连接MulticastSocket mcs = new MulticastSocket();//2.创建数据包打包数据String str = "你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("224.0.0.1");int port = 10086;DatagramPacket dp = new DatagramPacket(bytes, bytes.length,address,port);//3.发送消息mcs.send(dp);//4.关闭连接mcs.close();}
}

接收端:
步骤:
①创建组播连接,使用MultiCastSocket
②将当前连接加入组播地址
③创建DatagramPacket对象接收数据
④解析数据
⑤关闭连接

/*** @author Watching* * @date 2023/5/27* * Describe:接收组播消息*/
public class ReceiveMessageDemo2 {public static void main(String[] args) throws IOException {//1.建立mcs连接,并且填写发送端的端口MulticastSocket mcs = new MulticastSocket(10086);//2.将当前本机连接加入组播InetAddress address = InetAddress.getByName("224.0.0.1");mcs.joinGroup(address);//3.创建DatagramPacket接收数据byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);//4.接收数据mcs.receive(dp);//5.解析数据int port = dp.getPort();InetAddress ip = dp.getAddress();int length = dp.getLength();byte[] data = dp.getData();System.out.println(new String(data, 0, length));System.out.println("数据来自 [" + ip + "] 端口 [" + port + "]");//5.关闭连接mcs.close();}
}

可以多创建两个类,并运行他们,当发送端的代码执行后,每个添加进组播的连接都能接收到数据

广播

将单播的代码创建数据包DatagramPacket时,将发送的地址改为255.255.255.255就成了广播,局域网中的所有设备都能受到消息。

TCP协议

TCP协议的特点就是面向连接,要在确保连接成功之后才会传输数据,应用场景比如下载软件,发送邮件等。下载软件丢失了数据,可能会导致软件安装不成功,发送邮件丢失数据可能会导致邮件内容错乱。
在这里插入图片描述

TCP通信程序

在这里插入图片描述
客户端代码编写步骤
①创建客户端Socket对象与指定服务端连接
Socket(String host,int port);
②获取输出流,写数据
OutputStream getOutputStream
③释放资源

/*** @author Watching* * @date 2023/5/27* * Describe:tcp协议客户端*/
public class Client {public static void main(String[] args) throws IOException {//tcp协议发送数据//1.创建socket连接对象//细节:创建对象的同时会连接服务端,如果连接不上,会直接报错 Exception in thread "main" java.net.ConnectException: Connection refused: connectSocket socket =  new Socket("127.0.0.1",10086);//这行代码就是在创建连接(三次握手//2.从连接通道中获取输出流,将数据输出给服务端OutputStream outputStream = socket.getOutputStream();String str = "你好!";outputStream.write(str.getBytes());//3.关闭资源outputStream.close();socket.close();//断开连接,四次挥手协议,保证连接通道中的数据已经处理完成了}
}

服务端代码编写步骤
①创建服务器端的socket对象(ServerSocket)
ServerSocker(int port)
②监听客户端连接,返回Socket对象
Socket accept()
③获取输入流,读数据,并把数据显示在控制台
InputStream getInputStream()
④释放资源

/*** @author Watching* * @date 2023/5/27* * Describe:tcp协议服务端*/
public class Server {public static void main(String[] args) throws IOException {//服务端 接收数据//1.创建服务端连接ServerSocket ss = new ServerSocket(10086);//需要绑定一个端口号,以供客户端访问//2.监听客户端的连接Socket accept = ss.accept();//accept方法也是一个阻塞式的方法//3.从连接通道中获取输入流InputStream is = accept.getInputStream();byte[] bytes = new byte[1024];int len;while ((len = is.read(bytes)) != -1) {System.out.println(new String(bytes,0,len));}//4.释放资源is.close();ss.close();}
}

3次握手,4次挥手
3次握手建立连接:
在这里插入图片描述
4次挥手断开连接:
在这里插入图片描述

总结

在这里插入图片描述


http://www.ppmy.cn/news/190466.html

相关文章

Rust 笔记:Rust 语言中的枚举

Rust 笔记 Rust 语言中的枚举 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/…

一个简易的多GPU服务器监控程序

前言 因为实验室有很多台 GPU 服务器,每次要运行代码都要一台一台跑上去看GPU有没有人用,所以就写了一个这种小程序。 https://github.com/rikonaka/watchcorgi效果图 curl http://127.0.0.1:7070/info >> 2023-06-03 12:01:31 [watchcorgi] --…

python: zip 和unzip用法

a [1, 2] b [1, 3] zipped zip(a, b) zipped <zip at 0xa857448> list(zipped) [(1, 1), (2, 3)] c, d zip(*zip(a, b)) c, d list(c), list(d) ([1, 2], [1, 3])

zipfile.BadZipFile: File is not a zip file

zipfile.BadZipFile: File is not a zip file的问题复现步骤&#xff1a; 使用openpyxl的save函数&#xff0c;将数据保存在Excel文件中。在没有保存完成的情况下&#xff0c;又使用load_workbook函数加载该Excel文件。 解决方法&#xff1a;在执行完save前&#xff0c;不要使…

”拒绝访问,压缩包无法解压,压缩文件zipped无法创建指定的目录“的解决方法

电脑重装系统之后偶然间解压缩的时候提示拒绝访问&#xff0c;无法创建指定的目录。 分析应该是权限的问题&#xff0c;然后尝试给目标文件夹添加当前账户的控制许可&#xff0c;如下图&#xff1a; 再次解压即可完成。 原因应该是重装系统之后新的账户和原系统的硬盘文件之间的…

zip与zip(*)

zip创建一个聚合了来自每个可迭代对象中元素的迭代器。 zip返回一个元组的迭代器&#xff0c;其中的第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素。 当所输入可迭代对象中最短的一个被耗尽时&#xff0c;迭代器将停止迭代。 zip*相当于zip的逆操作&#xff08;…

python zip(*zipped)的疑问

zipped zip([one, two, three], [1, 2, 3]) print(zipped) print(list(zipped)) print(zipped) letter, number zip(*zipped) # *将元组解压为列表&#xff0c;返回二维矩阵&#xff0c;再打包为元组&#xff0c;拆包为两个变量 print("num_zip: ", letter, numbe…

Windows11 拒绝访问压缩(zipped)文件夹

最近windows10被自动升级到windows11&#xff0c;使用的一个工具zip压缩包突然就无法解压了&#xff0c;提示&#xff1a; 拒绝访问压缩&#xff08;zipped)文件夹&#xff0c;提取文件之前&#xff0c;必须更改这个压缩文件夹的权限。 我的尝试&#xff1a;更改了这个压缩包文…