黑马程序员--网络编程

     -----------  android培训 java培训 、java学习型技术博客、期待与您交流! ------------

 

 

关键字:网络编程、IP地址、端口、传输协议、网络模型、UDP、TCP、Socket

 

网络编程

数据通信的原理:数据传输。和本机编程的不同在于,涉及到了网络。

网络通讯的要素:IP地址、端口号、传输协议(通讯规则)。

网络通讯过程:

1. 找到对方的IP地址。

2. 将数据发送到对方主机的指定应用程序上。用数字来标识这些程序,称为“端口”。

3. 定义通讯规则,称为协议。国际组织定义了通用的协议,即TCP/IP。局域网、广域网都可以使用。也可以通过其他的协议构建自己的局域网,防止信息泄露。

IP地址

网络中设备的标识。不易记忆,可以使用主机名(网址)。

特殊的IP地址:127.0.0.1,默认的本地回环地址,本机名:localhost。可以用于测试网卡,使用dos,输入:ping 127.0.0.1。还有部分地址被保留,用于局域网,例如192开头,不同的局域网可以使用相同的地址。局域网的地址可以自定义,只要统一即可。

随着IP地址的减少,使用子网,一片区域的计算机使用同一个IP地址,内部是局域网。IPv6即6段IP地址,包含字母和数字。

端口号

用于标识进程的逻辑地址,不同进程的标识。

端口数字的范围:0到65535。0到1024为系统程序使用,凡是网络应用程序,都必须有数字标识,而且可以更改。

传输协议

主要协议类型:TCP和UDP。

传输方式:在网络传输过程中,针对不同程序、不同功能,按照层次对其进行划分。每个层次都有自己所做的事情。

网络模型:OSI参考模型、TCP/IP模型

OSI参考模型:开放式网络模型。

将每一层的特有信息加入,称为“数据封包”。解析数据,每层都在读自己能够识别的数据,也叫数据拆包。网络编程主要负责的是传输层和网际层。javaweb开发负责应用层。每层都有自己的协议(通讯规则),传输层协议是TCP和UDP,网际层协议是IP,应用层协议是HTTP和FTP。

 

通讯要素在java中的体现

IP地址

IP地址:将IP地址值封装进对象。127.0.0.1默认名:localhost,名字可以改。网址本质上是IP地址,为了方便记忆,将数字变成好记的字母,称为主机名,例如www.google.com,即网址。

InetAddress类表示互联网协议的IP地址,通过静态的getLocalHost()方法获得InetAddress对象,再通过getHostAddress(),获得本机IP地址;getHostName()获得本机名。

获取任意一台主机的IP地址对象:通过主机名获得IP地址对象,static InetAddress getByName(String host)。如果IP地址和主机名没有在网络上,即没有构成映射关系,本机名仍然是IP地址。以获取IP地址为主,因为本机名还需要解析。主机名可以是IP地址也可以是网址。因为可能有多台主机,所以返回的IP地址不唯一,通过getAllByName(String host),返回IP地址构成的数组。

 

端口

只是数字,没有封装成对象。                                                   

 

传输协议

UDP:1. 将数据及源和目的封装在数据包中,不需要建立连接。就是说,对方是否在线不重要,例如,QQ聊天、QQ的离线发送、网络视频会议、对讲机。在就收,不在就仍。需要明确对方的地址和端口。

2. 每个数据包的大小限制在64K内。3. 因为无连接,数据会丢失,是不可靠协议。4.不需要建立连接,不需要确认对方是否在线,速度快

TCP:建立连接,形成传输数据的通道,也就是说,通讯时,对方必须在;单方面断开的话,数据停止传输。在连接中进行大数据传输,不需要封装数据包。通过三次握手完成连接,是可靠协议。每次都必须建立连接,消耗资源,效率比较低。例如,打电话、下载。

三次握手:“在吗?”“在。”“我知道了。”通过三次握手,建立传输通道,确认双方是否都在线。

 

Socket

Socket是为网络服务提供的一种机制,意思是“插座”,可以理解为港口,上下货的地方,有了这个上下货的地方,数据才能传输。所谓网络编程,就是Socket编程。

网络通信的实质就是Socket间的通信,两端都有Socket。数据在2个Socket之间通过IO传输。想要通信的话,必须要有Socket。网卡、网线是物理传输介质。

 

UDP传输

每个协议都有自己不同的建立Socket的方式,即传输数据的方式。UDP特有的传输方式,即如何建立Socket服务的方式,对应2种对象,即DatagramSocketDatagramPacket。依据数据的方向,分为发送端和接受端。

DatagramSocket,此类表示用来发送和接收数据报包的Socket。2个端点都需要有这个对象。通过receive()和send()接受和发送数据。

DatagramPacket,此类表示数据报包。用于无连接的包投递服务。既可以接受、提取数据,也可以封装数据。包里面有数据、源地址、端口和目的地址、端口,因为数据比较多,所以封装成对象操作比较方便。发送数据包一定要带地址,即InetAddress对象。通过构造函数中参数的不同,分为接受型数据包和发送型数据包

必须要掌握Socket的工作流程。

通过UDP的数据方式,将数据发送出去。定义发送端。

思路:1.建立Socket服务。2.提供数据被封装到数据包中。3.通过Socket的发送功能发送。4.关闭资源。

具体步骤如下:

1. 创建UDP服务,即创建DatagramSocket对象。例如,DatagramSocket ds = new DategramSocket();。发送端可以指定端口,也可以使用系统随机分配的端口。端口如果没有被释放,会存在内存中。

2. 确定数据,并将数据封装成包。格式:DatagramPacket(byte[] buf, int length, InetAddress address, int port)。例如,DatagramPacket dp =

new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10086);

   3. 通过Socket中的send()方法,将数据发送出去。ds.send(dp);

   4. 关闭资源。ds.close();

   5. 处理异常。

   发送端和接受端应该放在2个文件中。

 

   通过UDP的数据方式,接受数据。定义接受端。

   思路:

1. 定义UDP的Socket服务。通常会监听一个端口,就是给这个网络程序定义一个数字标识,也就是门牌号。如果不定义,系统会随机指定标识,无法接受数据。

BindException,绑定异常。一个Socket服务只能使用一个端口,不能侵占别人的端口,所以Socket建立一次足矣。程序被关闭,端口被释放,这个端口才能被再次使用。

2. 定义一个数据包,为了存储接受到的字节数据。数据包对象中有更多功能可以提取字节数据中不同的数据信息。

3. 通过Socket服务中的receive()方法,将接受到的数据存入已经定义好的数据包中。

4. 通过数据包对象的特有功能,将不同的信息取出,打印在控制台上。

5. 关闭资源。

具体步骤如下:

   1. 创建Socket服务,建立端点。例如,DatagramSocket ds = new DatagramSocket(10086);加上数字标识,便于接受数据。

   2. 定义数据包,储存数据,例如,DatagramPacket dp = new DatagramPacket(buf,buf.length);字节数组最大可以定义到1024*64。

   3. 通过receive()方法将接受到的数据存入数据包中。例如,ds.receive(dp);。该方法为阻塞式方法,如果没有接受到数据,会自动等待。

   4. 通过数据包中的方法获得相应的数据,例如,String data = new String(dp.getData(),0,dp.getLength());。getPort(),获得发送端的数字标识。

   5. 关闭资源,可选。如果想要接受数据,需要一直开机。

   net包和io包经常合用。

   特殊的地址,广播地址。例如,192.168.1.0和192.168.1.255,前者代表网络段,后者代表广播地址,可以通过该地址向所有192.168.1开头的地址(计算机)发广播。

   聊天软件

将发送数据和接受数据的程序合用后,构成一个聊天软件。每一端都可以发送数据并接受数据,也就是说,每一端都有2个线程。一个Socket只能提供一种服务,要么发送,要么接受。2个Socket走2个线程,可以保证收发同时。

 

TCP传输

两端分别是客户端Socket和服务器端ServerSocket。建立连接后,使用IO流进行数据的传输。

客户端,空参数的对象需要使用connect()连接服务器端。通过查阅Socket对象,发现该对象建立时,就可以去连接指定的主机。因为TCP是面向连接的,所以在建立Socket服务时,需要有服务器端存在。形成通路后,通过该通路传输数据。

连接成功后,会建立通路,通路里面已经有Socket的网络流存在,通过getInputStream()和getOutputStream()可以获得输入流和输出流,从而完成对数据的操作。有了通路,也就有了流。Socket内部已经封装完毕。

客户端建立,具体步骤如下:

1. 创建客户端的Socket服务,并指定需要连接的目的主机和端口。例如,Socket s = new Socket("127.0.0.1",10086);

2. 为了发送数据,获取Socket流中的输出流,即OutputStream,数据会写入输出流,并随网络自动发送到对应的主机上。例如,OutputStream out = s.getOutputStream();

3. 关闭Socket服务。

为了防止服务器端将数据发到错误的客户端,服务器端本身没有流对象,它会使用客户端的流对象和客户端通信,也就是拿到了客户端对象。

定义服务端接受数据。具体思路如下:

1. 建立服务端的Socket服务,即ServerSocket,并监听一个端口。

2. 通过ServerSocket中的accept()方法,获取连接过来的客户端对象。该方法为阻塞式方法,没有连接会等待。

3. 客户端发送数据后,服务器端使用客户端对象,并通过获得该客户端的读取流来读取数据。源是网络流,基本操作和IO流一致。

4. 关闭服务器端,可选。会关闭客户端,防止浪费服务器端的资源。

服务器端建立,具体步骤如下:

1. 建立服务器端的Socket服务,并监听一个端口。例如,ServerSocket ss = new ServerSocket(10086);

2. 通过accept()方法获得连接过来的客户端对象。例如,Socket so = ss.accept();。注意一定要获得客户端的IP地址,方便日后使用。

3. 获取客户端发送的数据,使用客户端的读取流来读取。例如,InputStream in = so.getInputStream();

4. 关闭客户端。

 

客户端给服务器端发送数据,服务端收到后,给客户端反馈信息,也就是“三次握手”。思路如下:

1. 客户端将数据发送到服务器端后,需要建立一个输入流,准备读取服务器端发来的反馈信息。

2. 服务器端收到数据后,发送一个数据到客户端,表明收到数据。

3. 客户端收到数据,表示连接已经建立。

4. 两边都使用阻塞式方法,read()和accept(),等待信息,不会产生冲突。

客户端与服务器端之间数据的传输

客户端,既然是操作设备上的数据,可以使用IO技术,并按照IO技术的规律来思考。源:键盘录入等。目的:网络输出流,网络设备。客户端内部也有源和目的。

现象:客户端和服务端都等待。因为客户端和服务端都有阻塞式方法,read()和accept(),如果这些方法没有读到结束标记,会一直等待,所以需要刷新、换行等操作。

客户端的结束标识会发送到服务器端,从而结束服务器端的流。

建立端口需要try,可能会出现各种异常;建立各种流也需要处理异常。

客户端传输文件,内部需要判断文件是否存在,外部需要先把文件名字发出去,以便于服务器端可以建立同名的文件。如果文件存在,加上标识后存储。

文件的上传,最关键的问题是结束标记。

利用“时间戳”作为结束标识,在客户端,以当时的时间作为结束标记,如果服务器端读到了这个时间,关闭流。发送基本数据类型,使用时间戳比较方便。System.currentMillions()。

使用更多的是,通过Socket中的shutdownInput()和shutdownOutput()关闭流,内部也是使用标记。客户端写入数据结束后,给服务器端发送一个标记,即shutdoenOutput(),关闭客户端的输出流,相当于给流中加入结束标记-1,通知写入结束。

 

 

 

   ----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值