------- android培训、java培训、期待与您交流! ----------
Java网络编程
1、网络编程:两个或者以上的设备传输数据
1)、发送数据
2)、接收数据
谁来实现发送数据和接受数据的功能?编程语言的API
程序员的工作:明白通信原理 调用API
———————————————————————————————————————
假设发送端A(客户端) 接收端B(服务器)
要A和B进行通讯,首先需要建立连接,那么如何建立连接?
两要素:
IP:标识一台设备地址(到哪里找到设备)
域名:IP难记忆,域名易记忆 中间由DNS(域名服务器)进行IPßà域名
(单有IP地址不够,因为A和B主机通信,实际上是A和B上的两个进程通信)
Port:标识一个进程(线程)
这样IP + Port 就确定了A和B的连接(Socket连接)
Socket:
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
常见的客户端:浏览器
常见的服务端:Tomcat(软件)
———————————————————————————————————————
连接是建立了,双方如何明白彼此在说什么呢?比如打电话是用英语还是汉语沟通
通信的规则:协议
通信过程实际上非常复杂:计算机里面只有0和1,我们在QQ上确传输图片?
为了处理这个复杂的通信过程:网络分层模型
网络分层模型:TCP/IP 五层模型:各层各司其责,共同完成通信任务
这样主机A和B之间的通信,分解为层和层之间的通信,各层都需要相应的协议进行”沟通”
应用层:如http协议下传输一张图片
传输层:封装(拆)上层数据 分配端口号
TCP:传输控制协议 UDP:用户数据保协议
网络层:封装(拆)上层数据 IP协议 IP地址 解决路由选择
链路层:封装(拆)上层数据
物理层:0 1 传输
———————————————————————————————————————
网络层IP协议:
Java中对IP协议抽象:
InetAddress:详细信息阅读API文档
无构造方法:
InetAddress getByName(Stringhost):根据主机名获取IP对象
InetAddress getLocalHost():获取本机IP对象
getHostAddress():返回IP对象字符串表示的IP地址
getHostName():返回IP对象的主机名
getAddress():返回IP对象的原始IP地址,以字节数组表示
传输层协议:
网络编程通用步骤(TCP or UDP):
客户端(发送端):
1、 建立网络连接
需要知道服务器的IP地址和对外提供的端口号
若是数据库服务器,还需要带着用户名和密码去连接
2、交换数据
3、关闭网络连接
服务器端(接收端):
1、监听端口
监听一个端口,等待客户端的连接请求
2、获得连接
3、交换数据
4、关闭连接
UDP:无需连接的不可靠传输,速度快,64byte
UDP数据包格式: +数据
UDP接收端编程涉及的步骤是4个部分:建立连接、发送数据、接收数据和关闭连接
1)连接建立
发送端使用系统随机分配的一个本地计算机的未用端口号,可以通过指定连接使用的端口号来创建发送端连接,一般在建立发送端连接时没有必要指定端口号
2)发送数据(封装数据)
在发送数据时,需要将需要发送的数据内容首先转换为byte数组,然后将数据内容、接收端IP和接收端端口号一起构造成一个DatagramPacket类型的对象
3)UDP接收端编程中接收数据
UDP发送端也需要接收数据?
4)关闭连接
UDP方式接收端端网络编程涉及的步骤是:建立连接、接收数据、分析数据和关闭连接
1)连接建立
由于接收端端的端口需要固定,所以一般在建立接收端端连接时,都指定端口号
2)接收数据
3)解析数据
4)关闭连接
接收端的连接可以一直开着
Java中的UDP通信的实现类:
UDP是公共协议,Java根据面向对象的思想,将UDP相关内容进行抽象
DatagramSocket(封装socket):详细信息阅读API文档
DatagramSocket类表示用来发送和接收数据报包的套接字, 数据报套接字是包投递服务的发送或接收点,DatagramSocket实现的就是发送数据时的发射器,以及接收数据时的监听器的角色。类比于TCP中的网络连接,该类既可以用于实现发送端连接,也可以用于实现发送端端连接。
构造方法:
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket(int port, InetAddress laddr)
创建数据报套接字,将其绑定到指定的本地地址
成员方法:
receive(DatagramPacket p) :从此套接字接收数据报包
void send(DatagramPacket p):从此套接字发送数据报包
bind(SocketAddress addr):将此 DatagramSocket 绑定到特定的地址和端口
void close():关闭此数据报套接字
void connect(InetAddress address, int port) :将套接字连接到此套接字的远程地址
void connect(SocketAddress addr) :将此套接字连接到远程套接字地址
void disconnect():断开套接字的连接。
getInetAddress():返回此套接字连接的地址
InetAddress getLocalAddress():获取套接字绑定的本地地址
getPort():返回此套接字连接的端口
getLocalPort():返回套接字绑定的本地端口
DatagramPacket(封装数据包):详细信息阅读API文档
DatagramPacket类实现对于网络中传输的数据封装,也就是说,该类的对象代表网络中交换的数据。在UDP方式的网络编程中,无论是需要发送的数据还是需要接收的数据,都必须被处理成DatagramPacket类型的对象
构造方法:
用于发送的数据包:指定发送内容,目的IP,目的端口
public DatagramPacket(byte[] buf,int length,InetAddress address,intport)
用于接收的数据包:指定包长,注意包里面包含发送端的IP和端口
public DatagramPacket(byte[] buf,int length)
成员方法:
getAddress():返回接收或发送此数据报文的机器的IP地址
getData():返回接收的数据或发送出的数据
getLength():返回发送出的或接收到的数据的长度
getPort():返回接收或发送该数据报文的远程主机端口号
对于发送的数据包:
setAddress(InetAddress address):设置接收端的IP地址
setPort(int port):设置接收端的端口号
TCP:建立连接的可靠传输 速度慢大量数据
TCP数据报格式:
TCP三次握手机制:
第一次握手:客户端发送一个SYN给服务器,然后等待服务器的回发确认信息
第二次握手:服务器发送一个SYN-ACK给客户端,确认已经收到客户端发来的信息
第三次握手:客户端接收到服务器发来的确认信息后,再回馈一个ACK给服务器
TCP连接建立
ACK:TCP数据包首部中的确认标志,对已接收到的TCP报文进行确认
SYN:TCP/IP建立连接时使用的握手信号
TCP四次断开机制:
因为TCP/IP的连接是全双工的,所以每个方向都要单独进行关闭
当TCP单方向上的数据传输完后,都会再送一个FIN过去,告诉对方我这方向上的数据将要关闭了,请你做好准备。当对方接到FIN后就会通知应用层TCP连接已经终止了这一方向上的数据的传输。发送FIN通常是应用层进行关闭的结果。
第一次:客户端向服务器发送数据后,将FIN置1,通知将要关闭这一方向上的数据连接
第二次:服务器接受到FIN后,关闭该方向上的数据的连接,将ACK置1
第三次:服务器向客户端申请反方向上的数据连接的断开,将FIN置1
第四次:客户端接到服务器发来的申请,将ACK置1,双方同时关闭连接
TCP客户端编程涉及的步骤:
1)建立连接
创建客户端socket服务,建议明确目的IP地址和目的端口号
2)交换数据
若连接建立成功,说明数据传输通道(socket流)已建立,socket流是底层自动建立的,有socke输出流和socket输入流,根据面向对象的思想,由Socket对象获取socket流,分别是getOutputStream和getInputStream
发送客户端数据:往socket输出流OutputStream里面写数据
接收服务器返回的数据:从socket输入流InputStream里面读数据
3)关闭连接
TCP客户端编程涉及的步骤:
1)监听端口
创建ServerSocket对象,指定服务器监听的端口号
2)等待连接
等待连接:Socket accept():获取连接过来的客户端Socket对象,服务端自身不需要流,获取连接过来的客户端socket即可,它客户端原始的Socket对象不同,方向正好相反:
原始Socket对象:
Socket:[addr=/192.168.1.245,port=8888,localport=64531]
ServerSocket获取的Socket对象:
Socket[addr=/192.168.1.245,port=64531,localport=8888]
3)交换数据
通过accept获取的Socket对象来获取socket输入输出流,交换数据
接收来自客户端的数据:从socket输入流InputStream里面读数据
给客户端返回信息:往socket输出流OutputStream里面写数据
4)关闭连接
因为根据ServerSocket分别创建了每一个连接过来的Socket对象,因此当首先关闭它
服务器ServerSocket通常不关闭
参考下图:
Java中TCP通信的实现类:
Socket(封装客户端socket):详细信息查看API文档
构造函数:
Socket():
未连接的socket,使用系统默认的SocketImpl
Socket(InetAddress address,int port):
Socket(String host,int port):
连接到指定的地址
成员方法:
InputStream getInputStream():获取socket输入流
OutputStream getOutputStream():获取socket输出流
connect(SocketAddress endpoint):同服务端建立连接
ServerSocket(封装服务器端socket):详细信息查看API文档
构造函数:
ServerSocket(intport):
创建服务器socket,绑定指定的端口
成员方法:
Socket accept():获取连接过来的客户端socket
getInetAddress():获取连接到此socket的远端IP地址
getLocalAddress():获取连接到此socket的本机IP地址
———————————————————————————————————————
应用层协议Http:
Tomcat服务器:
Tomcat是软件,对外提供可访问的Web资源
Tomcat能够处理客户端请求,对外提供Servlet接口,只要实现了Servlet接口的类作为参数传递给Tomcat,它都能帮我们做出相应的处理。Servlet就是Java脚本片段
Interface Servlet的继承体系:
Interface Servlet
---class HttpServlet
---interface JspPage
---interface HttpJspPage
Tomcat的配置非常重要
JavaWeb的学习
HTTP分析工具和包:
Firebug:Firefox 插件
HttpClient:模拟浏览器功能,实质就是封装了HTTP协议
HTPP请求和响应(详细的信息查阅相关文档):
客户端发送的请求:
GET / HTTP/1.1
Accept:text/html, application/xhtml+xml, */*
Accept-Language:zh-CN
User-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Accept-Encoding:gzip, deflate
Host:192.168.1.156:9090
Connection:Keep-Alive
……
// 空行:请求消息头和请求体之间有空行
// 请求体:如注册输入的信息,登陆输入的信息
具体分析:
GET / HTTP/1.1
请求行 GET:请求方式 /myweb/MyHtml.html:请求的资源路径 HTTP/1.1:http协议版本
(客户端和服务端都必须遵循HTTP协议,才能进行通信,IE和tomcat都内置了HTTP解析引擎)
// 请求消息头(客户端告诉服务端的信息) 格式:属性名:属性值
Accept:text/html, application/xhtml+xml, */*
// 告诉服务器支持的语言
Accept-Language:zh-CN
// 告诉服务器端用户信息
User-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
// 告诉服务器端,客户端支持的压缩格式
Accept-Encoding:gzip, deflate
// 客户端要访问的主机
Host:192.168.1.156:9090
Connection:Keep-Alive
// 空行:请求消息头和请求体之间有空行
// 请求体:如注册输入的信息,登陆输入的信息
服务端发回应答消息:
HTTP/1.1 200OK // 应答行,HTTP协议版本 应答状态码 应答状态描述信息
// 应答消息头
Server:Apache-Coyote/1.1
Accept-Ranges:bytes
ETag:W/"1369-1345969876930"
Last-Modified:Sun, 26 Aug 2012 08:31:16 GMT
Content-Type:text/html
Content-Length:1369
Date: Sat, 29Sep 2012 09:50:20 GMT
Connection:close
……
// 空行
// 应答体
<html>
<head>
<title>MyHtml.html</title>
<meta http-equiv="keywords"content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is mypage">
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<!--<link rel="stylesheet" type="text/css"href="./styles.css">-->
</head>
<body>
This is my HTML page. <br>
<dl>
<dt>上层项目内容</dt>
<dd>下层项目</dd>
</dl>
<ultype="square">
<li>无序项目类表</li>
<li>无序项目类表</li>
<li>无序项目类表</li>
<li>无序项目类表</li>
</ul>
<oltype="a">
<li>有序的项目类表</li>
<li>有序的项目类表</li>
<li>有序的项目类表</li>
<li>有序的项目类表</li>
</ol>
</body>
</html>
Http解析过程:
IE向Tomcat发送HTTP请求信息,Tomcat启动HTTP解析引擎,解析HTTP请求信息;Tomcat向IE发送应答消息(应答消息头和应答体),IE启动HTTP解析引擎,解析应答消息头
解析完发现主体数据是HTML形式,IE启动HTML解析引擎解析应答体,仅将应答体显示出来
mybrowser向Tomcat发送HTTP请求信息,虽然mybrowser没有内置HTTP解析引擎,但是仿照HTTP请求消息格式发送HTTP请求信息,Tomcat解析,发回应答消息
但是,mybrowser露馅了,mybrowser无法解析应答消息头,于是将所有的信息显示出来了(包括应答消息头)
URL:统一资源定位器
Java中把URL抽象:URL类(详细信息查阅API文档)