本篇开始我们用Java语言,一步一步去编写一个简单的聊天室,实现单人私聊、多人群聊、文件发送等功能。聊天室系列第一篇,主要概括相关知识,用Java去实现相关操作,其中包括:网络模型、TCP/IP协议概念;IP类、端口类、URL类的相关方法使用。
一、开篇
1、网络
首先我们要明白每个通讯设备都是一个节点,多个节点联系成了网络。且每个设备都有它的IP地址,从公网到内网一 一区分。我们用IP地址定位一个设备,同一IP地址相当于同一公寓,不同端口号代表着这个公寓中不相同的房间号。这样可以将不同设备的同一软件进行通信。
URL(统一资源定位符)的作用是:定位到同一软件的不同资源。相当于你寄包裹,要先定位到小区(IP),再定位到房间号(端口),最后对应到你的姓名(URL)。
网络特点:①资源共享 ②信息传输与集中处理 ③负载均衡与分布处理(包括高并发、高性能、高可用)
关于协议:彼此沟通需要制定协议。协议使通讯变得更规范、更畅通、更方便。
2、通讯协议
计算机网络中实现通讯必须有一定约定,即通讯协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。
协议使通讯变得更规范、更畅通、更方便。
①TCP:一种面向连接的、可靠的、基于字节流的运输层通讯协议。
特点:占用系统资源多、效率低、可靠的点到点的连接。上层有HTTP、SMTP、FTP协议。通讯双方有主次之分。
②UDP:无连接、提供面向事务的简单不可靠信息传送服务。可能丢失,可以广播发送,简单,开销小。上层有DNS、SNMP协议。通讯双方平等。
通讯中的接口:是节点间的通讯工具,使彼此之间能够进行信息交换。
3、网络分层
<1> 分层模型
由于节点之间联系复杂,在制定协议时,把复杂复杂成分分解成一些简单成分,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系。
最常见的网络模型有:OSI模型和TCP/IP模型,其中OSI模型只是理论上的参考模型,实际中我们用TCP/IP模型更多一点。TCP/IP协议将OSI网络(七层)模型简化成四层,如下图所示:
<2> 数据封装
由于用户传输数据比较大,一次性发送出去十分困难,于是就需要把数据分成许多片段,再按照一次次序发送出去,这个过程就需要对数据进行封装。
其中PDU指协议数据单元,包括协议头、数据、协议尾。发送方处理数据的方式是从高层到底层,逐层进行数据封装。
①应用层:准备数据,交给传输层
②传输层:接收数据并添加TCP头部,数据单元叫段(Segment)将段交给网络层
③网络层:接收段并添加IP头部,此数据单元叫包(Packet)将包交给数据链路层。
④数据链路层:接收包添加MAC头部和尾部,叫帧(Frame)将帧交给物理层
⑤物理层:将接收到的数据转换为比特流,在网线中传输。
<3> 数据拆封
等层通讯的过程,将数据拆包,从底层到高层,对数据解封装。
①物理层:接收到比特流,经过处理后将数据交给数据链路层。
②数据链路层:将接收到的数据转化为数据帧,在去除MAC头部和尾部,这个过程称为解封,再将包交给网络层。
③网络层:接收到包,去除IP头部,将段交给传输层
④传输层:接收到段,去除TCP头部,将数据交给应用层。
⑤应用层:处理数据。
4、补充:
UDP:不可靠、不安全、高效、不面向连接
TCP:可靠、安全、不高效、面向连接
网络编程:关注底层传输
网页编程:关注应用开发
B/S:Browser/Server(浏览器/服务器)结构,在公网上
C/S:Client/Server(客户机/服务器)结构,在局域网上
二、IP地址
1、作用
IP定位计算机,Port定位软件,URL定义网络上每一个资源。
2、IP特点:
①每个通讯实体,即节点都有自己的IP地址
②通讯集群,要求就近原则
③IP地址分类:
IPV4:32位地址,四段8位,如192.168.0.1
IPV6:128位地址,8个16位整数,之间用:隔开
④特殊的IP:
127.0.0.1 本机地址
192.168.0.0-192.168.255.255私有地址,非注册
3、Java中获取IP地址
①用getLocalHost方法InetAddress对象
②根据域名得到InetAddress对象
DNS是域名解析器,将IP转为域名字符串,或者将
域名映射成IP地址。
③根据IP得到InetAddress对象
4、InetAddress类
public class IPtest {
public static void main(String[] args) throws UnknownHostException {
//使用getLocalHost方法创建InetAddress对象
InetAddress ip_address=InetAddress.getLocalHost();
System.out.println(ip_address.getHostName());//输出本机名
System.out.println(ip_address.getHostAddress());//输出本机IP地址
//根据域名得到InetAddress对象
ip_address=InetAddress.getByName("www.taobao.com");
System.out.println(ip_address.getHostName());//输出域名
System.out.println(ip_address.getHostAddress());//输出对应IP地址
//根据IP得到InetAddress对象
ip_address=InetAddress.getByName("42.48.120.253");
System.out.println(ip_address.getHostAddress());//输出淘宝网的IP地址
System.out.println(ip_address.getHostName());//如果IP不存在或者DNS服务器不允许域名和IP地址的映射,输出IP而不是域名
}
}
输出结果:
LAPTOP-5PG67USC
192.168.237.1
www.taobao.com
42.48.120.253
42.48.120.253
三、端口
1、概念
这里指网络虚拟端口,一个字(16位)的二进制整数,0-65535
2、端口分类
公认端口:0-1023
注册端口:1024-49151 分配给用户进程或应用程序
私有/动态端口: 49152-65535
同一协议下端口不要冲突
80 - HTTP
8080- tomcat外部服务器
1521- Oracle
3306- mysql
3、相关命令提示符
查看所有端口:netstat -ano
查看指定端口:netstat -aon|findstr"808"
查看指定进程:tasklist|findstr"808"
查看具体程序:使用任务管理器查看PID
4、InetSocketAddress类
/*
* 端口:与软件映射,由2个字节表示
* 1、构造器
* InetSocketAddress("域名|地址",端口);
* 2、方法
* getAddress()
* getPort()
* getHostName()
*/
public class Porttest {
public static void main(String[] args){
//包含端口
InetSocketAddress addr1=new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress addr2=new InetSocketAddress("localhost",9000);
// System.out.println(addr1.getHostName());
// System.out.println(addr1.getAddress());
// System.out.println(addr2.getHostName());
System.out.println(addr2.getAddress());
System.out.println(addr1.getPort());
System.out.println(addr2.getPort());
}
}
输出结果:
localhost/127.0.0.1
8080
9000
四、URL的基本用法
1、区分:
URL:统一资源定位符
URN:统一资源名称(例如磁力链接)
URI:统一资源标识符
2、格式
协议//主机名或服务器域名(IP地址):端口号/资源文件名?请求参数#锚点
其中锚点:同一个页面或同一个网站不同页面的定位。而超链接是不同的页面或网站的跳转
3、网络三大基石
URL、html(超功能标记语言)、HTTP
4、URL类
public class URLtest1 {
public static void main(String[] args) throws MalformedURLException{
URL url=new URL("http://www.baidu.com:80/index.html?uname=shsxt&age=18#a");
//并不会检验是否合法
System.out.println("协议:"+url.getProtocol());
System.out.println("主机名:"+url.getHost());
System.out.println("端口号:"+url.getPort());
System.out.println("资源路径:"+url.getPath());
System.out.println("查询部分(请求参数):"+url.getQuery());
System.out.println("锚点:"+url.getRef());
System.out.println("资源文件:"+url.getFile());
}
}
输出结果:
协议:http
主机名:www.baidu.com
端口号:80
资源路径:/index.html
查询部分(请求参数):uname=shsxt&age=18
锚点:a
资源文件:/index.html?uname=shsxt&age=18
5、爬虫获取网页信息
爬取京东网页信息:
/*
* 1、URL获取数据
* 2、下载
*/
public class Spidertest1 {
public static void main(String[] args) throws Exception{
//获取URL
URL url=new URL("https://www.jd.com");
//下载
InputStream is=url.openStream(); //IO字节流
BufferedReader br=new BufferedReader(new InputStreamReader(is,"UTF-8")); //字符流
String msg=null;
while(null!=(msg=br.readLine())){
System.out.println(msg);
}
br.close();
//分析
//处理
}
}
爬取大众点评网页信息,直接爬取会被拒绝掉,可通过模拟浏览器解决:
public class Spidertest2 {
public static void main(String[] args) throws Exception{
//获取URL
URL url=new URL("https://www.dianping.com");
//下载
//模拟浏览器
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
//请求方式:1、get拿取(相对不安全,量小) 2、post提交(相对安全,量大)
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent","Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/74.0.3729.131 Safari/537.36");
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")); //字符流
String msg=null;
while(null!=(msg=br.readLine())){
System.out.println(msg);
}
br.close();
//分析
//处理
}
}
其中User-Agent信息可在网页中按Fn+f12进入开发人员工具获取。