本
文
摘
要
网络编程概述
网络编程介绍
原来,我们写的程序,都是直接将数据保存在本机上,要么是内存中,要么是硬盘上;
如果要将数据传输到其他人电脑上,就需要使用网络;
那什么是网络呢?
网络的概念:
通过各种中间设备(例如网线、交换机、路由器、光纤、卫星、信号塔等等)将不同的通信终端(电脑、手机、ATM机、监控摄像头等等)连接起来,就形成了网络;
网络编程 :
就是编写一种程序,可以通过计算机网络和其它计算机上的程序进行数据交换。
在这个过程中,我们要学习研究的还是编程,不是网络;
CS和BS架构介绍
软件架构:
CS:Client/Server 客户端/服务端开发软件的时候,程序员需要开发2套软件,一个是给用户使用的客户端程序,一个是给服务器运行服务端程序。开发周期长,开发的成本高,服务器中的服务软件升级,导致客户端程序也随着升级。
好处:可以把一些运算放在客户端的电脑上运行。降低服务器的压力。
BS:Browser / Server 浏览器/ 服务端浏览器不需要用户安装。操作系统自带浏览器。程序员在开发的时候,只需要开发服务端的程序即可。
降低的开发的成本,以及后期维护的成本。
弊端:把以前可以在客户端运行的计算,全部转嫁到服务端。
网络模型(了解)
要学习网络编程,我们就要先了解一下网络模型;
什么是网络模型呢?
我们知道,在现实生活中的网络中,有各种不同的设备和程序在运行;
这些设备是不同厂家生产的,这些程序也是不同的公司编写的;
他们之间要能正常通信,必须要遵守某种约定;
所以人们将网络中的东西按照功能进行划分,并且制定好不同功能之间通信的标准,就形成了网络模型;
网络模型一般有两种:OSI(Open System Interconnection开放系统互连)参考模型 和TCP/IP模型;他们的对应关系如下:
网络模型7层概述:
应用层: 主要是各种具体的应用软件;例如,要给其他人发送图片,需要找一个软件,比如QQ、飞秋、浏览器等,这些就属于应用层的东西;
表示层: 连接应用层和会话层,主要实现数据的转换处理,如加密解密、压缩解压缩、编码解码等;例如,要发送的图片,是人能够直接识别的数据,但计算机不能直接识别;要使用计算机将图片发送出去,必须先将图片转换为计算机能够识别的数据;
会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)传输层:定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。网络层:主要将从下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输。 物理层: 主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。网络编程的三要素
IP介绍
IP:
IP地址,就是计算机在网络中的唯一标识;
在网络中,一台计算机要和其它计算机区分开,需要有个唯一标识;因为计算机是通过网卡接入网络的,所以这个唯一标识是计算机的网卡地址;
网卡是一个硬件,每个网卡在生产时就固定了一个全球唯一的地址;
因为这个地址很不方便记忆,所以网络为每个接入的网卡又分配了一个唯一标识,就是IP地址;
IP地址一般在机器接入网络时由路由器分配,是一个逻辑地址;
IP有两种版本:
IPv4:使用32位数字表示,总共2 ^32个,共有42亿多将近43亿个IP资源。肯定不够用。
IPv6:使用128位数字表示,总共2^128个,大约3.4×10^38个IP资源,近乎无限的。
有几个特殊IP:
127.0.0.1 是本地回环地址,表示本机(localhost)
x.x.x.255 广播地址
例如,发送信息到192.168.1.26,就只能发给这个人,其他人收不到;
发送信息到192.168.1.255,就可以发给1号段的所有电脑,只要在这个局域网中;
x.x.x.1网关(连接不同网络的地址)
域名解析
由于IP地址也不容易记忆,因此又给每个ip绑定了一个名称。这个名称被称为(域名)。
我们上网时在浏览器地址里面输入的就是网址,例如:
传智播客:www.itcast.cn
快学大数据:www.kuaixueit.com
百度:www.baidu.com
那么问题来了:为啥我用域名能找到对应的计算机服务器呢?
实际上,每个合法的域名,都会对应一个IP地址;
通过域名找到对应的计算机的方法:
1)本地域名解析
在我们电脑中有一个文件:C:\Windows\System32\Drivers\etc文件夹下有一个文件:hosts
这个文件中定义的是:域名和IP的对应关系。
当我们向浏览器中输入一个域名,按回车键,浏览器就会去找这个文件,看看我们的文件中有没有这个域名对应的ip
如果没有,就去DNS服务器找解析;
DNS服务器解析DNS服务器也网络中的一些计算机,里面保存了网址和IP的对应信息;
全世界所有网站,只要是合法注册了的,在注册的时候,都会把自己的网址和IP提交到DNS服务器里面;
端口
我们可以通过IP找到网络中的某台计算机。但是计算机中可能同时运行了很多个程序,例如迅雷、QQ等;如何确定数据应该发送给我们想要的程序呢?
这个时候就要用端口了。
端口号,就是正在运行的网络程序在计算机中的标识;
端口号的特点:
A:端口号是0到65535的数字;其中,0到1024是系统使用或保留的端口,我们不要使用;
B:计算机中每一个网络进程都至少要占用一个端口号;
C:同一个端口号只能被一个进程使用,不能同时被多个进程使用;
D:端口号只是在程序运行时被使用,程序一旦结束,端口号就会作为系统资源被释放;
通过使用360等软件可以查看所有被使用的端口号;
在命令行窗口中可以使用命令行 netstat -ano 查看本机所有正在使用的端口:
再使用命令 tasklist|findstr pid 可以根据占用端口的程序的pid找到对应的程序:
常用端口:
mysql:3306
服务器:80 8080
协议
协议:就是计算机通信的规则
UDP(User Datagram Protocol,用户数据报协议)的特点:
A:面向无连接,发送一方不用关心接收一方是否在线,就直接发送数据;如果对方在就可以接收数据,如果不在,就丢弃数据;
B:封装数据包
C:限制大小
D:不可靠
E:速度快
举例:类似发短信;
TCP(Tran *** ission Control Protocol 传输控制协议)的特点:
A:不限制大小
B:需要通过三次握手建立连接
C:可靠
D:速度慢,效率低
相当于打电话;
例如:
飞秋既可以聊天,也可以传文件;
聊天: 要求速度非常快,可靠性不是非常高,一般就是用UDP协议;
传文件: 这个要求可靠性非常高,数据大小也不应该有限制,所以一般都使用TCP协议;
地址和套接字
那我们正式来演示一下使用java代码实现网络编程;
要进行网络通信,需要知道其它计算机的IP地址,java中使用InetAddress类描述IP这个事物;
InetAddress类(IP对象)
Socket介绍
UDP传输
UDP中两个重要的类
使用UDP协议和其他机器进行通信,就像现实中发快递一样;
在使用这种协议发送数据时,首先需要一个数据报包对象,将我们要发送的数据装起来,然后同时在数据报包对象中传递目标ip和端口;
然后,使用socket对象将数据报包对象发出去(相当于发快递时包裹打好后,就需要通过快递公司发出去);
DatagramPacket:
DatagramSocket:
发送方发送数据报包的方法:
下面这个是给接收方使用;
接收方接受数据报包的方法:
关闭socket,释放资源的方法
UDP程序演示
发送数据:
步骤:
创建一个数据报包对象,将要发送的数据和目标ip、端口都封装起来;创建一个数据报Socket对象,调用上面创建的Socket对象的send方法,将这个数据报包发送出去关闭套接字 public class UDPSendDemo1 { public static void main(String[] args) throws IOException { //需求:编写程序,使用UDP协议,给本机的12345端口发送一句话:你好,快学大数据! String msg = "你好,快学大数据!"; byte[] data = msg.getBytes(); //1、创建一个数据报包对象,将要发送的数据和接受方的IP端口都封装起来; DatagramPacket dp = new DatagramPacket(data,data.length,InetAddress.getByName("127.0.0.1"),12345); //2、创建一个UDP协议的Socket对象,将上面创建好的包发送出去 DatagramSocket ds = new DatagramSocket(); //3、调用socket的方法发送数据 ds.send(dp); //4、关闭socket,释放资源 ds.close(); } }如果发出去的数据报包没有人接收,不会报错,而是直接就会被丢弃
接收数据:
步骤:
创建一个数据报包对象,用于包装传过来的数据定义一个Socket对象,监听指定端口,专门用来接受发送到这个端口的数据;3、调用方法接收:程序执行到这一步的时候,会阻塞起来,一直到有数据发送过来,才会继续往下执行。
解析数据报包,取出各种数据关闭socket对象,释放资源public class UDPReciveDemo1 { public static void main(String[] args) throws IOException { //1、创建一个空的数据报包对象,用来接受收到的数据 DatagramPacket dp = new DatagramPacket(new byte[1024],1024); //2、创建一个接收方的Socket对象,监听12345端口 DatagramSocket ds = new DatagramSocket(12345); //3、调用接收方Socket的方法,接受数据 ds.receive(dp);//程序启动后,会阻塞在这一步,知道有数据接受到,才会往下执行 //4、解析收到的数据 InetAddress address = dp.getAddress();//获取发送方的ip int port = dp.getPort();//获取发送方的端口 byte[] byts = dp.getData();//获取接受的数据 int length = dp.getLength();//获取发送的数据的长度 System.out.println("收到["+address.getHostAddress()+":"+port+"]发送的数据:"+new String(byts,0,length)); //5、关闭socket,释放资源 ds.close(); } }收到消息后给发送者一个反馈信息
接收端代码:
public class UDPReciveDemo2 { public static void main(String[] args) throws IOException { //1、创建一个空的数据报包对象,用来接受收到的数据 DatagramPacket dp = new DatagramPacket(new byte[1024],1024); //2、创建一个接收方的Socket对象,监听12345端口 DatagramSocket ds = new DatagramSocket(12345); //3、调用接收方Socket的方法,接受数据 ds.receive(dp);//程序启动后,会阻塞在这一步,知道有数据接受到,才会往下执行 //4、解析收到的数据 InetAddress address = dp.getAddress();//获取发送方的ip int port = dp.getPort();//获取发送方的端口 byte[] byts = dp.getData();//获取接受的数据 int length = dp.getLength();//获取发送的数据的长度 System.out.println("我是接收方,我收到["+address.getHostAddress()+":"+port+"]发送的数据:"+new String(byts,0,length)); //5、给发送方返回一个数据,告诉对方已经收到数据 //创建一个数据报包对象,用来封装给发送方返回的数据,以及发送方的ip和端口 byts = "来信已收到,谢谢!".getBytes(); dp = new DatagramPacket(byts,byts.length,address,port); ds.send(dp); //6、关闭socket,释放资源 ds.close(); } }发送端代码:
public class UDPSendDemo2 { public static void main(String[] args) throws IOException { //需求:编写程序,使用UDP协议,给本机的12345端口发送一句话:你好,快学大数据! String msg = "你好,快学大数据!"; byte[] data = msg.getBytes(); //1、创建一个数据报包对象,将要发送的数据和接受方的IP端口都封装起来; DatagramPacket dp = new DatagramPacket(data,data.length,InetAddress.getByName("127.0.0.1"),12345); //2、创建一个UDP协议的Socket对象,将上面创建好的包发送出去 DatagramSocket ds = new DatagramSocket(); //3、调用socket的方法发送数据 ds.send(dp); //4、创建空的DatagramPacket对象,用来收数据 dp = new DatagramPacket(new byte[1024],1024); ds.receive(dp); //5、解析接收方返回的数据 InetAddress address = dp.getAddress();//获取发送方的ip int port = dp.getPort();//获取发送方的端口 byte[] byts = dp.getData();//获取接受的数据 int length = dp.getLength();//获取发送的数据的长度 System.out.println("我是发送方,我收到["+address.getHostAddress()+":"+port+"]返回的数据:"+new String(byts,0,length)); //6、关闭socket,释放资源 ds.close(); } }TCP编程
TCP的Socket介绍
在建立TCP连接时,需要一方先向另一方提出连接请求;首先发起请求的一方叫做客户端,接收客户端请求的一方叫做服务端;
因为TCP连接中存在两个不同的角色(客户端和服务端),而网络连接中都需要通过Socket进行,所以Java中使用了两个Socket类来实现TCP协议:
客户端socket;Socket;
服务端socket:ServerSocket;
Socket介绍:
ServerSocket介绍: