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

  1. 二十三、Java基础--------网络编程

    Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析. 常见的网络协议:UDP.TCP UDP 1. 将数据源和目 ...

  2. JAVA的网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  3. Java Socket 网络编程心跳设计概念

    Java Socket 网络编程心跳设计概念   1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...

  4. 20145325张梓靖 实验五 "JAVA的网络编程"

    20145325张梓靖 实验五 "JAVA的网络编程" 实验内容 使用 JVAV语言 进行网络编程 对明文进行加密 设计过程 我完成的是客户端,服务端同伴 20145308刘昊阳 ...

  5. 【转】JAVA之网络编程

    转自:火之光 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者 ...

  6. JAVA的网络编程【转】

    JAVA的网络编程[转] Posted on 2009-12-03 18:04 火之光 阅读(93441) 评论(20) 编辑 收藏 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能, ...

  7. Java面向对象 网络编程 下

    Java面向对象 网络编程  下 知识概要:                   (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端:   ...

  8. Java面向对象 网络编程 上

     Java面向对象 网络编程 上 知识概要:                     (1)网络模型 (2)网络通讯要素 (3)UDP TCP 概念 (4)Socket (5)UDP TCP 传输 ...

  9. Java基础——网络编程(二)

    一.套接字 Socket 网络驱动程序提供给应用程序编程的接口和一种机制,可以比喻成一个港口码头 应用程序只要把货放在这,就算完成了货物的运送.它在应用程序中创建,通过一种绑定机制与驱动程序建立关系, ...

  10. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

随机推荐

  1. Vue系列---【自定义vue组件发布npm仓库】

    自定义vue组件发布npm仓库 参考链接:自定义vue组件发布npm仓库

  2. ybtoj 12F

    求值的话改为求解前缀和的值,通过两个前缀和相减即可得到每个值. 每次询问相当于给一个方程. 一共有 $n$ 个未知数,因此需要 $n$ 个方程,同时每个数都必须至少在方程中出现一次. 最小生成树求解即 ...

  3. Android 自定义View (二)

    一.前言 上节 通过一个简单的旋转环对自定义view作了一个基本的认识,本文将大致讲解下实现的思路以及对该view的一些可能的改进. 二.思路 主要通过重写 view 中的 onDraw() 方法,利 ...

  4. 【搭建】【转】搭建 yum仓库

    https://blog.csdn.net/wuxingge/article/details/100761637 3.2 服务端部署 1)安装软件程序(createrepo) yum install ...

  5. 3.Vue常用特性

    1.表单操作 (1)基于Vue的表单操作 input 单行文本 处理方式就是使用 v-model双向绑定data中的数据 1 <input type="text" v-mod ...

  6. 关于 用鼠标移动拖放 TabControl 标签 操作 实现 类

    1.相关说明已有 2.本类有可以改进的地方,如更进,希望交流 3.对多行标签的支持没做特别解决,效果不太好 4.初学者使用,即可通过其构造函数直接加载需要赋予此拖放功能的 TabControl 即可实 ...

  7. mysqld_safe Directory '/tmp/mysql' for UNIX socket file don't exists.

    报错版本:mysql-5.7.35 1.报错完整提示信息: [root@localhost bin]# 2022-11-15T04:04:43.122905Z mysqld_safe Logging ...

  8. (Linux)不挂断启动进程

    环境:腾讯云Ubuntu x86_64 问题:在配置应用时,需要让他后台启动,关闭ssh连接也要可以保持后台运行 解决办法: 1.使用nohup 参考链接:https://zhuanlan.zhihu ...

  9. Linux基础——操作系统

    1. 操作系统(Operation System,OS) 操作系统作为接口的示意图 如果想在裸机上运行自己所编写的程序,就必须用机器语言书写程序如果计算机上安装了操作系统,就可以在操作系统上安装支持的 ...

  10. 有时候用uniapp写项目时发现,Map组件在安卓真机可以缩放和移动,但是在ios真机就不行

    如果你的地图组件是放到popup组件里,是用弹框打开的,如何ios端不能缩放, 那你一定要看下这个弹框的层级是否比地图层级要高  z-index. 如果高于地图层级,那地图肯定是不能移动和缩放的