一、计算机网路基础概念
1、计算机网路 --百度百科
计算机网络,是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
从逻辑功能上看,计算机网络是以传输信息为基础目的,用通信线路将多个计算机连接起来的计算机系统的集合,一个计算机网络组成包括传输介质和通信设备。
虽然网络类型的划分标准各种各样,但是从地理范围划分是一种大家都认可的通用网络划分标准。按这种标准可以把各种网络类型划分为局域网、城域网、广域网和互联网四种。
2、网络分层
为了减少网络设计的复杂性,绝大多数网络采用分层设计方法。所谓分层设计方法,就是按照信息的流动过程将网络的整体功能分解为一个个的功能层,不同机器上的同等功能层之间采用相同的协议,同一机器上的相邻功能层之间通过接口进行信息传递。
计算机网络是指由通信线路互相连接的许多自主工作的计算机构成的集合体,各个部件之间以何种规则进行通信,就是网络模型研究的问题。
网络模型一般是指OSI七层参考模型和TCP/IP四层参考模型。这两个模型在网络中应用最为广泛。
开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。它从低到高分别是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
二、Java网络编程基础概念
Java网络编程:即通过使用套接字来达到进程间通信目的。API在java.net包下。
Java的网络编程主要涉及到的内容是Socket编程,倒不如说是Java的I/O编程,因为整个过程中关于服务端和客户端的socket创建也就那么两三行代码,其余的都是操作字节流,字符流等数据传输。
1、什么是Socket呢?
源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务。
简单地说,Socket套接字,就是两台主机之间逻辑连接的端点。TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket,本质上就是一组接口,是对TCP/IP协议的封装和应用(程序员层面上)。 .
2、网络编程三要素
IP地址、端口和协议(数据传递/交互的规则)
IP
IP,全称互联网协议地址,是指IP地址,意思是分配给用户上网使用的网际协议(英语:InternetProtocol,IP)的设备的数字标签。常见的IP地址分为IPv4与IPv6两大类
IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
在Java中,使用 java.net.InetAddress 类来表示IP地址
//方法等
public static void main(String[] args) throws IOException {
/**
* static InetAddress getLocalHost()
* 返回本地主机。
*/
InetAddress inetAddress = InetAddress.getLocalHost();
System.out.println(inetAddress); // administrator/192.68.69.10
/**
* String getHostName()
* 获取此IP地址的主机名。
*/
System.out.println(inetAddress.getHostName()); //administrator
/**
* String getHostAddress()
* 返回文本显示中的IP地址字符串。
*/
System.out.println(inetAddress.getHostAddress()); //192.68.69.10
/**
* byte[] getAddress()
* 返回此 InetAddress对象的原始IP地址。
*/
System.out.println(inetAddress.getAddress());
/**
* static InetAddress getByName(String host)
* 在给定主机名的情况下确定主机名称的IP地址。
*/
inetAddress = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress); //www.baidu.com/180.101.49.11
/**
* boolean isReachable(int timeout)
* 测试该地址是否可达。
*/
System.out.println(inetAddress.isReachable(3000)); //true
}
端口(port)
"端口"是英文port的意译,可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45网口,交换机路由器集线器等RJ45端口。电话使用RJ11插口也属于物理端口的范畴。
IP地址用来标识一台计算机,但是一台计算机上可能提供多种网络应用程序,用端口可区分这些不同的程序。
端口是虚拟的概念,并不是说在主机上真的有若干个端口。
通过端口,可以在一个主机上运行多个网络应用程序。端口的表示是一个16位的二进制整数,2个字节,对应十进制的0~65535。
在Java中,使用 java.net.InetSocketAddress 类来表示
//方法等
public static void main(String[] args) throws IOException {
/** 构造器
* InetSocketAddress(InetAddress addr, int port)
* 从IP地址和端口号创建套接字地址。
* InetSocketAddress(String hostname, int port)
* 从主机名和端口号创建套接字地址。
*/
//InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 10000);
InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getByName("www.baidu.com"), 10000);
/**
* String getHostName()
* 获得 hostname 。
*/
System.out.println(inetSocketAddress.getHostName()); //www.baidu.com
/**
* String getHostString()
* 如果没有主机名(使用文字创建),则返回主机名或地址的String形式。
*/
System.out.println(inetSocketAddress.getHostString()); //www.baidu.com
/**
* int getPort()
* 获取端口号。
*/
System.out.println(inetSocketAddress.getPort()); //10000
/**
* InetAddress getAddress()
* 获得 InetAddress 。
*/
System.out.println(inetSocketAddress.getAddress()); // www.baidu.com/180.101.49.12
}
协议 (protocol)
协议(Protocol):网络协议的简称,是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述。
URL
在www上,每一信息资源都有统一且唯一的地址,即统一资源定位符。Uniform Resource Locator。
如:https://localhost:8080/index.html ,有4部分组成。(协议,主机域名或IP,端口号,资源文件名)
网络三大基石:HTML,HTTP,URL
URI = URL+URN
URI:Uniform Resource Identifier ,统一资源标志符。
URL:Uniform Resource Locator,统一资源定位符。
URN:Uniform Resource Name,统一资源命名。
在Java中,使用 java.net.URL 类来表示URL
//方法等具体查看API
public static void main(String[] args) throws IOException {
URL url = new URL("https://www.baidu.com");
//获取此的授权部分 URL 。
System.out.println(url.getAuthority());
//获取此 URL的文件名。
System.out.println(url.getFile());
//获取端口
System.out.println(url.getPort());
//获取主机
System.out.println(url.getHost());
//获得默认端口
System.out.println(url.getDefaultPort());
//获得路径
System.out.println(url.getPath());
//获取该 URL的userInfo部分。
System.out.println(url.getUserInfo());
}
URLEncoder编码和URLDecoder解码
一般情况下,web应用中,当你的服务器,页面编码,请求时编码都已经修改为 utf-8后,依然乱码时,此时则应试着用下方所写到的方法使用URLDecoder将所乱码的数据进行解码,
简单说一下乱码的场景和简单转换时的执行原理:
首先,form表单提示数据时,默认Content-type:为 application/x-www-form-urlencoded,当然也可以是:multipart/form-data ,multipart/form-data 一般用做form表单以流的形式提交数据时,则设置,enctype为该form-data形式,
不过呢,一般情况下,提交方式为application/x-www-form-urlencoded MIME编码, 当环境等等都已经配置为统一编码后,仍然出现汉字传到后台 被解码处理的情况时(也就是所谓的乱码 ),此时可以尝试,使用URLDecoder进行解码再转换,然后转换为汉字,当然在使用场景上,其实还是有很多情况下需要区分的。
URLEncoder和URLDecoder用于完成普通字符串和application/x-www-form-urlencoded MIME字符串之间的相互转换.
public static void main(String[] args) throws IOException {
//获取平台默认的字符集
System.out.println(System.getProperty("file.encoding")); //UTF-8
String msg = "宝塔镇河妖abc";
//使用UTF-8编码
String msg1 = URLEncoder.encode(msg,"UTF-8");
System.out.println(msg1);//%E5%AE%9D%E5%A1%94%E9%95%87%E6%B2%B3%E5%A6%96abc
//使用UTF-8解码
String msg2 = URLDecoder.decode(msg1,"UTF-8");
System.out.println(msg2);//宝塔镇河妖abc
}
3、传输层协议:
TCP和UDP的区别:
TCP :面向连接(经历三次握手)、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。 服务端和客户端
UDP:面向非连接、传输不可靠(丢包[数据丢失])、用于传输少量数据(数据报包模式)、速度快。发送端和接收端
三、基于Socket的java网络编程
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。
一个Socket由一个IP地址和一个端口号唯一确定。
Socket编程通信主要涉及到客户端和服务器端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。
客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。
在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
1、简单的Client/Server程序
需求: 客户端连接服务端时,服务端向客户端发送消息
public class Server {
public static void main(String[] args) throws IOException {
// 1、创建服务器,指定端口 ServerSocket(int port)
ServerSocket serverSocket = new ServerSocket(10001);
// 2、接受连接该服务端的客户端对象,阻塞式
Socket client = serverSocket.accept();
System.out.println("一个客户端建立连接,IP:" + client.getInetAddress());
// 3、IO 操作
// 获取到客户端的输出流对象给客户端输出数据
boolean accept = true;
while (accept) {
String data = "服务器-->:" + client.getInetAddress() + "你来了";
PrintStream out = new PrintStream(client.getOutputStream());
out.print(data);
out.close();
}
// 4、关闭此套接字。
//serverSocket.close();
}
}
public class Client {
public static void main(String[] args) throws IOException {
// 1、创建客户端必须指定服务器的IP+端口,此时就在连接
Socket client = new Socket("127.0.0.1",10001);
// 2、IO操作,自动关闭流
// 获取客户端的输入流对象
Scanner sc = new Scanner(client.getInputStream());
while (sc.hasNextLine()) {
String str = sc.nextLine();
System.out.println(str);
}
sc.close();
// 3、关闭此套接字。
client.close();
}
}
参考文章:
简单记录下基础概念,自己使用的比较少,也有点不熟悉,写一点提升一点,对于Socket示例参考了其他文章,感谢其他作者