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. Centos7下搭建部署DoClever接口管理平台

    项目地址: github:https://github.com/sx1989827/DOClever 码云:https://gitee.com/sx1989827/SBDoc 1.根据官方文档,先安装 ...

  2. python 安装fbprophet模块的艰辛历程

    fbprophet这个模块是我目前见过最难装的一个模块,我安装这个包安装了3天,气死我了,需求的依赖包太多,而且对依赖包的版本有极高的要求,所以建议在装这个模块的时候在一个空的虚拟环境下安装,这样依赖 ...

  3. Linux(2)

    虚拟机关键配置名词解释 远程链接工具 linux准则 远程链接工具快捷键 系统相关命令 文件相关命令 linux目录结构 虚拟机关键配置名词解释 # 虚拟网络编辑器说明 桥接模式  # 可以访问互联网 ...

  4. 复杂数据类型(signal)的解读-C语言基础

    这一篇文章要探讨的是C语言中复杂数据类型的解读.涉及到signal()函数数据类型的解读(并不解释signal()的作用)以及对于数据类型的理解,属于C语言基础篇. 在开始解读signal()这种复杂 ...

  5. 【javascript】chormeV8源码阅读之 GC(垃圾回收)过程 笔记

    1.为何需要垃圾回收     在V8引擎逐行执行JavaScript代码的过程中,当遇到函数的情况时,会为其创建一个函数执行上下文(Context)环境并添加到调用堆栈的栈顶,函数的作用域(handl ...

  6. MySql.Data 链接MySql数据库 查询语句中带有中文的奇怪问题

    首先Nuget管理器安装MySql.Data 1.ado.net 直接链接 public static void Test() { MySqlConnection myconn = null; MyS ...

  7. GDB使用详解

    来源:GDB使用详解 - 知乎 (zhihu.com) 1. 概述 ​ GDB 全称"GNU symbolic debugger",从名称上不难看出,它诞生于 GNU 计划(同时诞 ...

  8. 使用loadrunner运行中问题(无代码生成解决方法)

    开始录制之后,不能成功录制,工具栏events一直是2,打开新网站不跳动,结束录制之后没有代码生成 进入软件,点击工具栏的录制,选择录制选项,将http高级如下设置 同时也要修改套接字,如下配置 当开 ...

  9. OSPF之路由过载overflower 及GR(Graceful Restart优雅重起)

  10. 如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权

    一.简介 我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是WebAPI,在 Net6.0中,有两类 WebAPI,一类是极简 WebAPI,它砍掉了很多冗余的东西,更纯粹的是做 ...