【JavaSE】网络编程
1. 网络编程概述
网络编程的目的:直接或者间接地通过网络协议与其他计算机实现数据交换,进行通讯。
网络编程两个主要的问题:
①如何精准地定位网络上的一台或多台主机,并定位主机上的特定应用
②找到主机后如何进行可靠高效的数据传输
1.1 网络通信要素
通信双方地址:
①IP地址(InetAddress):查找主机,对应问题一
唯一标识Internet上的计算机(通信实体)
本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
127.0.0.1,通常被称为本地回环地址(Loopback Address),不属于任何一个有类别地址类。它代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。在Windows操作系统中也有相似的定义,所以通常在安装网卡前就可以ping通这个本地回环地址。一般都会用来检查本地网络协议、基本数据接口等是否正常的。
IP地址分类方式一:
IPv4:4个字节,4个0-255,以点分十进制表示,如192.168.1.1
IPv6:16个字节128位,写成8个无符号整数,每个整数用4个十六进制位表示,数之间用:分开
IP地址分类方式二:
公网地址(万维网使用)和私有地址(局域网使用)
InetAddress
| 实例化方法 | |
|---|---|
| getByName("") | 形参地址为IP或者域名 |
| getLoopbackAddress() | 本地回环地址的域名IP |
| getLocalHost() | 主机网络域名IP |
InetAddress inetAddress = InetAddress.getByName("192.168.10.14");
System.out.println(inetAddress);///192.168.10.14
InetAddress inetAddress1 = InetAddress.getByName("www.bilibili.com");
System.out.println(inetAddress1);//www.bilibili.com/120.92.78.97
InetAddress inetAddress2 = InetAddress.getLocalHost();
System.out.println(inetAddress2);//LAPTOP-B4BJHS06/192.168.137.1
InetAddress inetAddress3 = InetAddress.getLoopbackAddress();
System.out.println(inetAddress3);//localhost/127.0.0.1
| 实例方法 | |
|---|---|
| getHostName() | |
| getHostAddress() |
一定的规则,即网络通信协议:
①OSI参考模型(过于理想化)
②TCP/IP参考模型(或TCP/IP协议)

②端口号:标识主机上的应用程序,对应问题二
被规定为不同的16位整数0-65535
端口分类:
①公认端口:0-1023,被预定义的服务通信占用。如Http:80,FTP:21,Telnet:23
②注册端口:1024-49151,分配给用户进程和应用程序,如Tomcat:8080,MySQL:3306,Oracle:1521
③动态、私有端口:49152-65535
端口号与IP的组合为网络套接字:Socket
1.2 网络协议
也即是通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。同层之间可以通信、上一层可以调用下一层,而与再下一层不再发生关系。
1.2.1 TCP/IP协议簇
传输层包括TCP(传输层控制协议)和UDP(用户数据报协议)。
TCP协议:
使用TCP协议前,先建立TCP连接,形成数据传输通道;传输前,采用“三次握手”的方式,进行可靠的点对点通信;客户端和服务端两个应用进程在连接中进行大数据量的传输,传输结束需要释放已经建立的连接,效率低。


TCP网络编程示例:Socket和ServerSocket
@Test
public void client() {
InetAddress inet = null;
Socket socket = null;
OutputStream os = null;
try {
inet = InetAddress.getByName("10.42.138.5");
socket = new Socket(inet, 8899);
os = socket.getOutputStream();
os.write("人类荣光永存!".getBytes(StandardCharsets.UTF_8));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(inet);
}
@Test
public void server() {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
while(true) {
try {
serverSocket = new ServerSocket(8899);
socket = serverSocket.accept();
is = socket.getInputStream();
// 方式一,数组长度不足会乱码,UTF汉字占两个字节
// int len;
// byte[] buffer = new byte[5];
// while((len = is.read(buffer)) != -1) {
// String str = new String(buffer);
// System.out.print(str);
// System.out.println();
// }
/*
人�
�荣�
��永
存�
����
*/
// 方式二:使用转换流将字节流转换为字符流
InputStreamReader isr = new InputStreamReader(is);
int len;
char[] chs = new char[1];
while ((len = isr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
System.out.println();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
通过Socket传输图片
@Test
public void nib() {
FileInputStream fis = null;
Socket socket = null;
OutputStream outputStream = null;
try {
File file = new File(".\\data\\2B\\2b.jpg");
// System.out.println(file.getAbsolutePath());
fis = new FileInputStream(file);
InetAddress inetAddress = InetAddress.getByName("10.42.138.5");
socket = new Socket(inetAddress, 8899);
outputStream = socket.getOutputStream();
int len;
byte[] bytes = new byte[1024];
while((len=fis.read(bytes))!=-1) {
outputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void kyuus() {
FileOutputStream fs = null;
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
while(true) {
try {
serverSocket = new ServerSocket(8899);
socket = serverSocket.accept();
File file = new File(".\\data\\9S\\2b.jpg");
fs = new FileOutputStream(file);
is = socket.getInputStream();
int len;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
fs.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
需要特别关注的是这一部分代码,file需要放在获取socket之后,否则会导致流无法写入
serverSocket = new ServerSocket(8899);
socket = serverSocket.accept();
File file = new File(".\\data\\9S\\2b.jpg");
fs = new FileOutputStream(file);
传输完成并回复消息:socket.shutdownOutput()
@Test
public void nib() {
FileInputStream fis = null;
Socket socket = null;
OutputStream outputStream = null;
try {
File file = new File(".\\data\\2B\\2b.jpg");
// System.out.println(file.getAbsolutePath());
fis = new FileInputStream(file);
InetAddress inetAddress = InetAddress.getByName("10.42.138.5");
socket = new Socket(inetAddress, 8899);
outputStream = socket.getOutputStream();
int len;
byte[] bytes = new byte[1024];
while((len=fis.read(bytes))!=-1) {
outputStream.write(bytes, 0, len);
}
socket.shutdownOutput();
InputStream is = socket.getInputStream();
byte[] bytes1 = new byte[1024];
while((len=is.read(bytes1))!=-1) {
System.out.println(new String(bytes1));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void kyuus() {
FileOutputStream fs = null;
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
while(true) {
try {
File file = new File(".\\data\\9S\\2b.jpg");
fs = new FileOutputStream(file);
serverSocket = new ServerSocket(8899);
socket = serverSocket.accept();
is = socket.getInputStream();
int len;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
fs.write(bytes, 0, len);
}
is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
char[] chs = new char[100];
while((len=isr.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
OutputStream os = socket.getOutputStream();
os.write("传输完成".getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
UDP协议:DatagramSocket和DatagramPacket
将数据、源、目的封装成数据报,不需要建立连接。每个数据包限制大小为64kb。由于不管对方是否准备好,接收方收到也不确认,因此是不可靠的。可以广播发送,发送数据结束时无序释放资源,开销小,速度快。适合传输一些视频。
UDP网络编程示例:
@Test
public void sender() {
DatagramSocket socket = null;
try {
InetAddress inet = InetAddress.getByName("localhost");
socket = new DatagramSocket();
byte[] data = "我是UDP发送方".getBytes(StandardCharsets.UTF_8);
DatagramPacket datagramPacket = new DatagramPacket(data, 0, data.length, inet, 8090);
socket.send(datagramPacket);
} catch (SocketException | UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
@Test
public void receiver() {
try {
InetAddress inet = InetAddress.getLocalHost();
DatagramSocket socket = new DatagramSocket(8090);
byte[] data = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(data, 0, data.length);
socket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
UDP与TCP的不同:
TCP必须是服务器端先启动,否则客户端先发送握手请求,没有响应便会断开TCP连接,无法再进行数据传送。而UDP是无连接协议,发送方发送数据不需要判断接收方是否接收,接收方如果后启动就会接收不到数据,但仍然能继续传送数据。
IP协议是网络层的主要协议,支持网间互连的数据通信。
1.3 URL编程:统一资源定位符
| 常用方法 | |
|---|---|
| getProtocol() | 协议名称 |
| getPath() | 资源路径 |
| getHost() | 主机域名 |
| getPort() | 端口号 |
| getFile() | 资源文件 |
| getQuery() | 关键字序列 |
URL url = new URL("http://localhost:8080/examples/beauty.jpg?username='admin'&pwd='123");
System.out.println(url.getProtocol());
System.out.println(url.getPort());
System.out.println(url.getPath());
System.out.println(url.getHost());
System.out.println(url.getFile());
System.out.println(url.getQuery());
【JavaSE】网络编程的更多相关文章
- JavaSE| 网络编程
URL URI(Uniform resource identifier):表示一个统一资源标识符 (URI) 引用,用来唯一的标识一个资源. URL(Uniform Resource Locator) ...
- JavaSE——网络编程基础知识
计算机网络的分类: 局域网(LAN) 指在一个较小地理范围内的各种计算机网络设备互联在一起的通信网络,可以包括一个或多个子网,通常局限在几千米的范围之内. 城域网(MAN) 主要由城域范围内的各个局域 ...
- [javaSE] 网络编程(概述)
网络通信的步骤, 1.找到对方的ip 2.数据发送到对方指定的应用程序上,为了标识这些应用程序,用数字进行标识,这个数字就是端口 3.定义通信规则,这个规则就称为协议 国际组织定义了通用协议 TCP/ ...
- [javaSE] 网络编程(TCP通信)
客户端A与服务端建立通信,服务端获取到客户端A的Socket对象,通过这个通路进行通信 客户端: 获取Socket对象,new出来,创建客户端的Socket服务,构造参数:Sting主机,int 端口 ...
- [javaSE] 网络编程(UDP通信)
UDP发送端 获取DatagramSocket对象,new出来 获取DatagramPacket对象,new出来,构造参数:byte[]数组,int长度,InetAddress对象,int端口 调用D ...
- [javaSE] 网络编程(TCP,UDP,Socket特点)
UDP特点: 面向无连接,把数据打包发过去,收不收得到我不管 数据大小有限制,一次不能超过64k,可以分成多个包 这是个不可靠的协议 速度很快 视频直播,凌波客户端,feiQ都是UDP协议 TCP特点 ...
- [javaSE] 网络编程(TCP服务端客户端互访阻塞)
客户端给服务端发送数据,服务端收到数据后,给客户端反馈数据 客户端: 获取Socket对象,new出来,构造参数:String的ip地址,int的端口号 调用Socket对象的getOutputStr ...
- [javaSE] 网络编程(浏览器客户端-自定义服务端)
获取ServerSocket对象,new出来构造参数:int类型端口号 调用ServerSocket对象的accept()方法,得到Socket对象 获取PrintWriter对象,new出来,构造参 ...
- [javaSE] 网络编程(URLConnection)
获取URL对象,new出来,构造参数:String的路径 调用URL对象的openConnection()方法,获取URLConnection对象 调用URLConnection对象的getInput ...
- [javaSE] 网络编程(URL)
获取URL对象,new出来,构造参数:String的路径 调用URL对象的getProtocal()方法,获取协议 调用URL对象的getHost()方法,获取主机 调用URL对象的getPath() ...
随机推荐
- Vue Yarn npm nodejs - 安装、配置
一.安装 node.js 1.从node.js官网下载并安装,安装时,安装路径可以修改为非C盘 2.使用 node --version 命令在 CMD 中查看 nodejs 安装的版本,显示了安装的版 ...
- centos虚拟机yum update报错Another app is currently holding the yum lock; waiting for it to exit...
1.运行yum update报错 [root@localhost ~]# yum update已加载插件:fastestmirror, langpacks/var/run/yum.pid 已被锁定,P ...
- git 更改子项目索引
git update-index --cacheinfo 160000 97ed2f63b07c73bad9a4d55e96e25292 source/lvdao/crf-sdk git reset ...
- UIPath踩坑记一UIpath中抓取数据后在tableau中无表头
UIpath抓取数据存在Excel中(Excel 应用程序范围),且已设置表头,但是放到tableau中无表头 更换为"写入范围(工作簿)",同时属性设置必须勾选"添加标 ...
- vue项目怎么链接开发服务器
在前后端分离的前提下,完成前端的页面开发,就可以开始链接开发服务器 安装axios到项目中 npm install axios --save 安装完成后问你的后端开发人员要IP 后端会给一个IP以及端 ...
- Docker-界面化
docker-ui docker-ui只能便于我们查看系统的相关信息,镜像或者容器.在界面上做简单的处理,可处理单机版Docker. docker pull uifd/ui-for-docker do ...
- laravel whereHas sum & addSelect sum
$users = User::select('id', 'username', 'coins', 'cut') ->when(request()->has('agent_tip_sum') ...
- Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件
Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布局.界面切换 [本章]Qt 学习笔记 - 第三章 - Qt的三驾马车之一 ...
- day06-静态资源访问&Rest风格
SpringBoot之静态资源访问&REST风格请求 1.SpringBoot静态资源访问 1.1基本介绍 只要静态资源是放在类路径下的:/static./public./resources. ...
- 全网最详细中英文ChatGPT-GPT-4示例文档-从0到1快速入门解析非结构化数据应用——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)
目录 Introduce 简介 setting 设置 Prompt 提示 Sample response 回复样本 API request 接口请求 python接口请求示例 node.js接口请求示 ...