网络编程

1. 网络通信协议

1.1 协议和七层模型

要使计算机连成的网络能够互通信息,需要对数据传输速率、传输代码、代码结构、传输控制步骤、出错控制等制定一组标准,这一组共同遵守的通信标准就是网络通信协议,不同的计算机之间必须使用相同的通讯协议才能进行通信。

七层模型,也称为OSI(Open System Interconnection)参考模型,是国际标准化组织(ISO)制定的一个用于计算机或通讯系统间互联的标准体系。它是一个七层的、抽象的模型体,不仅包括一系列抽象的术语或概念,也包括具体的协议。 ​ ISO 就是 Internationalization Standard Organization(国际标准组织)。

  • 应用层:

应用程序之间如何相互传递报文,比如HTTP协议,FTP协议

  • 传输层

传输层的作用是为两台主机之间的"应用进程"提供端到端的逻辑通信,比如TCP协议

  • 网络层互联层

    网络层互联层提供了主机到主机的通信,将传输层产生的数据包封装成分组数据包发送到目标主机,并提供路由选择能力. IP协议是网络层的主要协议,TCP和UDP都是用IP协议作为网络层协议.这一层的主要作用是给包加上源地址和目标地址,将数据包传送到目标地址.

  • 网络访问层

    网络访问层也可以称为网络接口层,以太网,WIFI,蓝牙就是工作在这一层,网络访问层提供了主机连接到物理网络需要的硬件和相关协议

1.2 TCP/IP协议

在Internet中TCP/IP协议是使用最为广泛的通讯协议。TCP/IP是英文Transmission Control Protocol/Internet Protocol的缩写,意思是“传输控制协议/网际协议”

TCP/IP协议(定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准):

Internet上不同系统之间互联的一组协议

为分散和不同类型的硬件提供通用的编程接口。

TCP/IP协议使Internet尽可能成为一个分散、无序的网络。

TCP是基于(面向)连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。

TCP协议建立连接需要三次会话(握手)

IP地址:网络中每台计算机的一个标识号

是一个逻辑地址.在实际中可以使用127.0.0.1表示本机,或者直接使用localhost代表本机

IP地址使用32位长度二进制数据表示,一般在实际中看到的大部分IP地址都是以十进制的数据形式表示的,如:192.168.1.3。

IP地址分类:

IP地址分为5类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数据不同。

NO. 地址分类 地址范围
1 A类地址 1.0.0.1——126.255.255.254
2 B类地址 128.0.0.1——191.255.255.254
3 C类地址 192.0.0.1——223.255.255.254
4 D类地址 224.0.0.1——239.255.255.254
5 E类地址 240.0.0.1——255.255.255.254

端口号:具有网络功能的应用软件的标识号

端口是一个软件结构,被客户程序或服务程序用来发送和接收数据,一台服务器有256*256个端口。

0-1023是公认端口号,即已经公认定义或为将要公认定义的软件保留的

1024-65535是并没有公共定义的端口号,用户可以自己定义这些端口的作用。

端口与协议有关:TCP和UDP的端口互不相干

2. 网络通信的实现

思考网络编程要解决的问题:

1.如何建立两个节点(电脑)之间的网络连接?

2.如何向另外一个节点(电脑)发送信息?

3.如何从外部节点(电脑)接收一个请求并给预响应?

4.如何利用网络协议(TCP,UDP)?

2.1 socket编程

套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。

当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。

java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

当然,这里的ServerSocket只是socket通信中的一种,实际上,socket通信有三种模式来让我们实现:

1.流式套接字

提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收,其实他对应使用的是TCP协议

2.数据报式套接字

面向无连接,数据报以独立包形式发送,不提供无差错保证,数据可能丢失或重复,并且接收顺序无序,其实他对应使用的是UDP协议

3.原始式套接字

该接口允许对较低层次协议,如IP直接访问。可以接收本机网卡上的数据帧或数据包,对监听网络流量和分析很有用

2.2 TCP协议通信

TCP是一个面向连接的,可靠的,基于字节流的传输层协议.

面向连接: 所谓的连接,指的是客户端与服务器端的连接,在双方相互通信之前,TCP需要三次握手建立连接.

可靠性:TCP花费了非常多的功夫保证连接的可靠性,这个可靠性体现在下面两个方面:

 1. TCP有状态: TCP会精确记录那些数据发送了,那些数据被对方接收了,那些没有被接收到,而且保证数据包按序到达,不允许半点差错.2. TCP可控制: 如果发现丢包或者网络不佳,TCP会根据具体的情况调整自己的行为,控制自己的发送速度或者重发.

使用TCP协议实现通信,需要使用流式套接字。即客户端采用socket,而服务器端采用ServerSocket来完成通信的方式

此时实现服务器端与客户端通信的思路:

其中,处理服务器端通信的ServerSocket类,其常见构造如下:

构造方法 说明
ServerSocket() 创建一个ServerSocket对象
ServerSocket(int port) 创建一个ServerSocket对象,并绑定到指定端口

ServerSocket常用方法如下:

常用方法 说明
Socket accept() 侦听并接收到此ServerSocket的连接,此方法在连接传入之前一直阻塞
void close() 使服务器释放占用的资源,并断开所有与客户端的连接
InetAddress getInetAddress() 返回当前服务器绑定的IP地址信息

处理客户端通信的Socket类:

Socket的构造共有9种,这里介绍2种常用的构造方法:

构造方法 说明
Socket(String host, int port) 向host主机的port端口发起连接请求
Socket(String host, int port, InetAddress localAddr, int localPort) 向host主机的port端口发起连接请求,发起请求的计算机为localAddr,端口为localPort

注意:InetAddress类表示互联网协议地址,包含IP地址,实际上就是java对IP地址的封装。

Socket的常用方法:

常用方法 说明
InetAddress getInetAddress() 返回与当前Socket对象关联的InetAddress对象
void shutdownInput() 此套接字的输入流置于“流的末尾”
void shutdownOutput() 禁用此套接字的输出流
InputStream getInputStream() 返回当前Socket对象关联的InputStream对象,它是服务器端向客户端发送回来的数据流.
OutputStream getOutputStream() 返回当前Socket 对象关联的OutputStream对象,它是客户端想服务器端发送的数据流
void close() 关闭该socket建立的连接

2.2.1 服务端编程

服务器实现代码如下:

package cn.gl.no1;
​
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
​
/*** 服务端* @author Administrator**/
public class Server {
​public static void main(String[] args) {ServerSocket server = null;Socket socket = null;try {//准备服务器端用的通讯对象(套接字),指明端口号为8888server = new ServerSocket(8888);//到指定端口去阻塞监听,一旦有客户端请求发送过来,那么立即自动与客户端建立连接socket = server.accept();System.out.println("服务器端准备ok");//我要发送到客户端的内容String msg = "你好,我是服务器,这是我的第一次通讯,请问你收到了吗";OutputStream os = socket.getOutputStream();//准备输出对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));bw.write(msg);bw.newLine();bw.flush();//接收客户端发送的信息InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String reply = br.readLine();System.out.println("我是服务器,接收到信息:"+reply);
​br.close();is.close();bw.close();os.close();socket.close();server.close();} catch (IOException e) {e.printStackTrace();}}
}

2.2.2 客户端实现

客户端实现代码如下:

package cn.gl.no1;
​
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
​
/*** 客户端* @author Administrator**/
public class Client {
​public static void main(String[] args) {Socket socket = null;try {socket = new Socket("localhost", 8888);System.out.println("客户端准备完成");
​//客户端开始接受请求InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String msg = br.readLine();System.out.println("我是客户端,接收到信息:"+msg);
​//客户端接收到服务器端的信息之后,需要反馈信息给服务器//客户端想要反馈给服务器端的信息 String reply = "我是客户端,收到你的信息,这是我的反馈";OutputStream os = socket.getOutputStream();//准备客户端的输出流BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));bw.write(reply);bw.newLine();
​bw.flush();bw.close();os.close();br.close();is.close();socket.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
​

2.3 UDP协议通信

UDP是一个面向无连接,不可靠的传输层协议.

需要用到两个类:DatagramSocket,DatagramPacket

DatagramSocket类的作用:发送和接收数据包的套接字,不维护连接状态,不产生输入输出流

DatagramPacket类:数据包,封装了数据,数据长度

DatagramPacket构造方法:

构造方法 说明
DatagramPacket(byte [] buf,int length,InetAddress address,int port) Buf是数据的字节数组,length是字节数组的长度,address是目标主机的IP地址,port是目标主机的端口 该构造用来构造对象,将长度为length的包发送到指定主机上的指定端口号

DatagramSocket的构造方法:

构造方法 说明
DatagramSocket() 创建DatagramSocket对象,并将其与本地主机上任何可用的端口绑定
DatagramSocket(int port) 创建一个DatagramSocket对象,并将其与本地主机上的指定端口绑定

注意:在UDP通信中,通信的双方中,至少有一方需要指定端口号

DatagramSocket的常用方法:

常用方法 说明
void send(DatagramPacket p) 发送指定的数据报
void receive(DatagramPacket p) 接收数据报.收到数据以后,存放在指定的DatagramPacket对象中
void close() 关闭当前的DatagramSocket对象

2.3.1 服务端实现

UDP通信中并不需要明确的服务器概念,双方几乎是一样的操作,如下见服务器代码实现:

package cn.gl.no1;
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
​
public class Client1 {
​public static void main(String[] args) {DatagramSocket socket = null;try {//参与通讯的两方,至少应该有一边指定端口号socket = new DatagramSocket();
​String msg = "我要发送的短信内容";//dp对象,是用来把要发送的信息打成一个数据包//数据长度不能超过64K//构造中可以传递四个参数://第一个参数,表示要发送的内容,需要转换成一个byte数组byte [] b = msg.getBytes();//第二个参数,表示发送内容的字节数int len = b.length;//第三个参数,表示IP地址封装的一个对象,类型是InetAddress,是接收方的地址InetAddress ia = InetAddress.getByName("localhost");//第四个参数,表示对方的端口号int port = 8888;DatagramPacket dp = new DatagramPacket(b, len, ia, port);
​socket.send(dp);
​byte [] bs = new byte[1024];int length = bs.length;DatagramPacket dpReceive = new DatagramPacket(bs, length);socket.receive(dpReceive);String reply = new String(bs,0,dpReceive.getLength());System.out.println("我是client1,收到信息:"+reply);
​
​socket.close();} catch (SocketException e) {e.printStackTrace();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

2.3.2 客户端实现

客户端实现代码如下:

package cn.gl.no1;
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
​
public class Client2 {
​public static void main(String[] args) {DatagramSocket socket = null;try {socket = new DatagramSocket(8888);
​//这里为了接收数据,也需要一个空的数据包//两个参数://第一个参数,表示一个空的byte数组,用来接收信息内容byte [] b = new byte[1024];//第二个参数,表示数组长度int len = b.length;DatagramPacket dp = new DatagramPacket(b, len);//接收信息socket.receive(dp);String msg = new String(b,0,dp.getLength());System.out.println("我是Client2,接收到信息:"+msg);
​String reply = "我很好,收到你的信息,很高兴,谢谢";byte [] bs = reply.getBytes();int length = bs.length;InetAddress ia = dp.getAddress();/*InetSocketAddress isa = (InetSocketAddress) dp.getSocketAddress();System.out.println("isa.getHostName():"+isa.getHostName());System.out.println("isa.getHostString():"+isa.getHostString());System.out.println("isa.getPort():"+isa.getPort());*/int port = dp.getPort();DatagramPacket dpReply = new DatagramPacket(bs, length, ia, port);      socket.send(dpReply);
​socket.close();} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

Java SE day 24 网络相关推荐

  1. JAVA SE 学习之网络开篇

    目录 1.什么是计算机网络? 2.什么是网络传输协议? 3.网络协议的分层 4.数据的封装与解封 5. ip地址 6.端口 7.URL 8.Socket 9. UDP协议 10. TCP协议 11.T ...

  2. Java SE 网络编程

    Java SE 网络编程 目录 Java SE 网络编程 1.计算机网络概念 2.网络通讯协议 2.2.通讯接口 3.网络分层 3.2.OSI七层协议|TCP/IP五层协议 3.3 . 封装 3.4. ...

  3. Java SE day21_网络编程

    Java SE day21_网络编程 如果一个类没有构造方法: 案例(UDP的Socket) 案例(键盘输入接受) 案例(多线程聊天) TCP连接 案例(阻塞) 案例(键盘录入-输出控制台) 案例(多 ...

  4. Java SE 6 新特性 Instrumentation 新功能

    系列内容: 此内容是该系列的一部分:Java SE 6 新特性 Instrumentation 简介 利用 Java 代码,即 java.lang.instrument 做动态 Instrumenta ...

  5. 【JAVA SE】第一章 Java语言概述、环境变量和HelloWorld

    第一章 Java语言概述.环境变量和HelloWorld 文章目录 第一章 Java语言概述.环境变量和HelloWorld 一.Java语言概述 1.Java简介 2.Java发展历史 3.Java ...

  6. Java SE 基础部分经典100道笔试题

    这100道题的范围主要是Java SE部分,正在学习Java SE的同学可以做一下,巩固一下学习的知识,也比较适合准备面试的同学复习使用.本题有90道选择题和10道填空题,选择题大部分是单选题,少数为 ...

  7. Java SE 基础知识

    Java SE 基础知识 1 2 @(Notes)[J2SE, Notes] VICTORY LOVES PREPARATION. 特别说明: 该文档在马克飞象查阅最佳: 本部分知识还在迭代中,欢迎补 ...

  8. JAVA SE基础笔记

    第一天  JDK安装.快捷键.JAVA语言特点 1.Java语言的概述 1.1 Java语言的背景 Java语言诞生于1995年,在编程语言排行榜占据重要的地位. Java语言之父是高斯林,以前隶属于 ...

  9. JAVA SE 语言编程-杨千锋-专题视频课程

    JAVA SE 语言编程-3572人已学习 课程介绍         第一周: 内容包括,Java环境搭建,变量,数据类型,二进制,if/else,switch,for,while,do while等 ...

最新文章

  1. cxf开发实践(添加SSL支持)
  2. 5行python代码讲清楚如何在区块链挖矿
  3. opencv中在图片上显示文本
  4. boost::date_time模块wrapping_int的测试程序
  5. 利用java反射调用类的的私有方法--转
  6. ZkServer服务启动的逻辑-QuorumPeer.start
  7. 一步步构建大型网站架构 [转]
  8. 惠普继续大裁员:未来3年计划裁撤7000-9000个岗位
  9. Python学习---基础函数的学习
  10. mysql主从配置,innobackup备份
  11. [TWRP 2.8.4 ] 小米 3W 中文-英文版本 twrp
  12. PMP-8. 项目经理的能力
  13. kotlin发音!2021年Android面试心得,安卓系列学习进阶视频
  14. sql查询结果 替换
  15. 巴比特 | 元宇宙每日必读:大厂的高薪、期权都不香了,互联网精英纷纷涌向的Web3,魅力到底有多大?...
  16. 腾讯微搭低代码(预约)总体介绍——工作室专用(客户端)
  17. [论文阅读]《Using Conditional Functional Dependency to Discover Abnormal Data in RDF Graphs》阅读笔记
  18. 快速将PDF图片转成PPT
  19. 自动变量,非自动变量,全局变量与局部变量
  20. netty基础教程-3、helloworld(cs模式)

热门文章

  1. 不知道怎样做自媒体视频剪辑?分享几个必备素材网站
  2. workflow 的审批流程的业务实现一
  3. 解决Cleartext HTTP traffic to 01.minipic.eastday.com not permitted
  4. 教程:Yolo5训练自己的数据集以及安装教程
  5. Jmeter简单操作
  6. python datetime 时间加一秒,一分钟
  7. 计算机体系结构(国防科大)-第七章-多处理机
  8. 2021年秋季PAT乙级题解(C语言)
  9. 使用GoogleChrome+JS代码批量删除QQ空间说说
  10. PPT:立体仓库详解及出入库效率计算