【Java SE】网络编程
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());
【Java SE】网络编程的更多相关文章
- 二十三、Java基础--------网络编程
Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析. 常见的网络协议:UDP.TCP UDP 1. 将数据源和目 ...
- JAVA的网络编程
网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...
- Java Socket 网络编程心跳设计概念
Java Socket 网络编程心跳设计概念 1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...
- 20145325张梓靖 实验五 "JAVA的网络编程"
20145325张梓靖 实验五 "JAVA的网络编程" 实验内容 使用 JVAV语言 进行网络编程 对明文进行加密 设计过程 我完成的是客户端,服务端同伴 20145308刘昊阳 ...
- 【转】JAVA之网络编程
转自:火之光 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者 ...
- JAVA的网络编程【转】
JAVA的网络编程[转] Posted on 2009-12-03 18:04 火之光 阅读(93441) 评论(20) 编辑 收藏 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能, ...
- Java面向对象 网络编程 下
Java面向对象 网络编程 下 知识概要: (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端: ...
- Java面向对象 网络编程 上
Java面向对象 网络编程 上 知识概要: (1)网络模型 (2)网络通讯要素 (3)UDP TCP 概念 (4)Socket (5)UDP TCP 传输 ...
- Java基础——网络编程(二)
一.套接字 Socket 网络驱动程序提供给应用程序编程的接口和一种机制,可以比喻成一个港口码头 应用程序只要把货放在这,就算完成了货物的运送.它在应用程序中创建,通过一种绑定机制与驱动程序建立关系, ...
- java基础-网络编程(Socket)技术选型入门之NIO技术
java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...
随机推荐
- Spring Boot 中的异步调用
通常我们开发的程序都是同步调用的,即程序按照代码的顺序一行一行的逐步往下执行,每一行代码都必须等待上一行代码执行完毕才能开始执行.而异步编程则没有这个限制,代码的调用不再是阻塞的.所以在一些情景下,通 ...
- Jmeter----Badboy录制
Badboy Badboy安装后出现错误,需要设置 Preferences-->General-->Enable Recording on Startup?的√去掉,play-->S ...
- golang sync.RWMutex总结笔记
背景 最近项目中遇到两次RWMutex死锁问题,所以稍微看了一下资料和源码,稍作记录 源码 type RWMutex struct { w Mutex // held if there are pen ...
- webpack逆向之报错Cannot read properties of undefined (reading 'call')
经典报错 记录一下: 1: 缺少模块 补上 2.主模块无法调用子模块 有可能网站用的数组形式的模块包,你用的是对象,调用方法就要改变. 改写过程中 用的是对象方式: 那么3号包调用的4号包 ...
- C#学习之详解C#Break ,Continue, Return
C#编程语法中break ,continue, return这三个常用的关键字的学习对于我们编程开发是十分有用的,那么本文就向你介绍break ,continue, return具体的语法规范. C# ...
- Laravel安装第一步:Windows 10 上laravel下载与安装需要注意。
1.下载了laravel,查看composer.json文件,搞清楚它需要的PHP版本 2.不要用 composer install !!! 用 composer -vvv install 这样 ...
- 会长哥哥帮助安装ubuntu
今晚突然想到要安装虚拟机,因为我原来上的python预科班里面讲解安装虚拟机,但是我当时没有安装上,导致预科班后面的课我没听懂,今天听课讲到字符和编码 所以想到了我的虚拟机,于是今晚很谨慎的求助会长大 ...
- IDEA设置自定义代码模板
1. 进入IDEA界面,File–>Settings 注:其中, $END$代表打印字符串后光标所处的位置 如: System.out.println($END$); 表示输出后光标在()里面.
- 西电oj135题 拼数字并排序
类别综合 时间限制 1S 内存限制 1000Kb 问题描述 对于输入的字符串(只包含字母和数字),将其中的连续数字拼接成整数,然后将这些整数按从大到小顺序输出.例如字符串"abc123d5e ...
- 表单笔记-Antd(Form)
antd表单使用笔记 import React, { useState, useEffect, useRef } from "react"; import { Form, Inpu ...