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】网络编程的更多相关文章

  1. JavaSE| 网络编程

    URL URI(Uniform resource identifier):表示一个统一资源标识符 (URI) 引用,用来唯一的标识一个资源. URL(Uniform Resource Locator) ...

  2. JavaSE——网络编程基础知识

    计算机网络的分类: 局域网(LAN) 指在一个较小地理范围内的各种计算机网络设备互联在一起的通信网络,可以包括一个或多个子网,通常局限在几千米的范围之内. 城域网(MAN) 主要由城域范围内的各个局域 ...

  3. [javaSE] 网络编程(概述)

    网络通信的步骤, 1.找到对方的ip 2.数据发送到对方指定的应用程序上,为了标识这些应用程序,用数字进行标识,这个数字就是端口 3.定义通信规则,这个规则就称为协议 国际组织定义了通用协议 TCP/ ...

  4. [javaSE] 网络编程(TCP通信)

    客户端A与服务端建立通信,服务端获取到客户端A的Socket对象,通过这个通路进行通信 客户端: 获取Socket对象,new出来,创建客户端的Socket服务,构造参数:Sting主机,int 端口 ...

  5. [javaSE] 网络编程(UDP通信)

    UDP发送端 获取DatagramSocket对象,new出来 获取DatagramPacket对象,new出来,构造参数:byte[]数组,int长度,InetAddress对象,int端口 调用D ...

  6. [javaSE] 网络编程(TCP,UDP,Socket特点)

    UDP特点: 面向无连接,把数据打包发过去,收不收得到我不管 数据大小有限制,一次不能超过64k,可以分成多个包 这是个不可靠的协议 速度很快 视频直播,凌波客户端,feiQ都是UDP协议 TCP特点 ...

  7. [javaSE] 网络编程(TCP服务端客户端互访阻塞)

    客户端给服务端发送数据,服务端收到数据后,给客户端反馈数据 客户端: 获取Socket对象,new出来,构造参数:String的ip地址,int的端口号 调用Socket对象的getOutputStr ...

  8. [javaSE] 网络编程(浏览器客户端-自定义服务端)

    获取ServerSocket对象,new出来构造参数:int类型端口号 调用ServerSocket对象的accept()方法,得到Socket对象 获取PrintWriter对象,new出来,构造参 ...

  9. [javaSE] 网络编程(URLConnection)

    获取URL对象,new出来,构造参数:String的路径 调用URL对象的openConnection()方法,获取URLConnection对象 调用URLConnection对象的getInput ...

  10. [javaSE] 网络编程(URL)

    获取URL对象,new出来,构造参数:String的路径 调用URL对象的getProtocal()方法,获取协议 调用URL对象的getHost()方法,获取主机 调用URL对象的getPath() ...

随机推荐

  1. 20181224蒋嘉豪-exp5

    网络对抗技术Exp5 信息搜集与漏洞扫描20181224jjh 目录 网络对抗技术Exp5 信息搜集与漏洞扫描20181224jjh 信息搜集技术与隐私保护--知识点总结 间接收集 直接收集 社会工程 ...

  2. springboot jodconverter openoffice 实现 office 文件 在线预览

    这个已是好几个月前做的,好多细节已记得不那边清楚了.今天部署到环境还遇到不少问题.总结下. 1.office 文件实现在线预览的一般思路就是,将文件转pdf,在通过pdf.js 实现在线浏览.这其中转 ...

  3. Javaheima20

    Java 学习内容 单元测试 反射 注解 动态代理 开发好的系统中存在很多的方法,如和对这些方法的正确性进行测试 如何在程序运行时取得到Class对象,然后取获得Class中的每个成分 注解是什么,具 ...

  4. IEEE会议论文投稿系统问题之一:WinEdt编译生成DVI文件的方法

    问题描述:如何将tex文件正确编译为dvi文件,以正常使用IEEE投稿系统? 方法: 1.打开WinEdt中的命令行: 2.使用latex TexFileName编译tex生成aux文件和dvi文件: ...

  5. tcpdump 对指定pod 进行抓包分析

    tcpdump kubectl get pod -n imas imas-chabot-759bc8c6cf-bvq7m -o json 获取到pod所在的容器信息,在对应的宿主机获取卡片信息. do ...

  6. 2.3Dmax界面_视图调整

    一.试图模型显示效果的切换 '默认是真实显示效果' 线框模式 快捷键F3 ----> 真实显示效果和线框显示效果的切换(切换到线框显示效果再按F3就切换到了真实显示效果). 线面模式 快捷键F4 ...

  7. 西电oj73题字符串处理

    问题描述 有一种简单的字符串压缩算法,对于字符串中连续出现的同一个英文字符,用该字符加上连续出现的次数来表示(连续出现次数小于3时不压缩).例如,字符串aaaaabbbabaaaaaaaaaaaaab ...

  8. vitrualbox虚拟机搭建

    参考:https://blog.csdn.net/weixin_45115705/article/details/100661644?depth_1-utm_source=distribute.pc_ ...

  9. vlan概述

    一.vlan是什么? vlan顾名思义就是虚拟局域网Virtual Local Area Network,为什么要划分vlan?划分vlan可以控制广播,增强网络安全性,简化网络管理. 二.vlan的 ...

  10. Google colab复现openpose+st-gcn的心路历程

    Google colab复现openpose+st-gcn的心路历程: 因为本人的大致研究方向为动作识别,加上自己的笔记本比较菜鸡,没有牛皮的显卡,所以采用了google的colab.在网上查了三天, ...