黑马程序员-13-java网络编程-概念及UDP、TCP连接
2015-05-28 15:46
846 查看
------- android培训、java培训、期待与您交流!
----------
网络编程
在掌握了基本的程序编写技巧后,我们来看一下Java网络编程。在这部分总结之前,我们首先需要掌握一些计算机网络的学科知识,这里给出了部分主要内容的概述:
端口:为进程间通信提供必要标识的数据标识,我们称之为端口。它是计算机程序为了区分不同进程而创立的区别方式。因此,端口号只具有本地意义,对应主机间通讯,在某种情况下必须指明对应接受传输数据端口号。
端口号分为两种:服务端使用端口号、客户端使用端口号。
服务端使用端口号又分为:熟知端口号、登记端口号。
熟知端口号:0~1023,IANA,即互联网地址指派机构,将此类端口派给了TCP/IP协议的一些重要程序。
登记端口号:1024~49151,此类端口号为一些没有熟知端口号的应用程序使用。想要使用登记端口号,则必须在IANA登记才可使用。
客户端使用端口号:又被称为短暂端口号,因为此类端口号只在客户进程运行时才会动态的选择调用。当用户进程结束时,此类端口则会自动释放。便于其他进程使用。此类端口号并没有具体使用要求,一般在程序运行时,都会由系统分配,并回收。
端口的存在,另一点就是为直达进程的网际进程间通信,打下了条件。
除了端口之外,在网际数据传输上,我们根据实际情况将计算机网络体系结构分为一下两种模型。
图8.计算机网络体系结构图
本质上,这两种模型都是对同一种事物,即网络,的不同描述。我们这里的Java程序,主要运用到的是TCP/IP中传输层、网际层,这两层的协议。如果是Java-Web开发,则会涉及应用层的协议。具体协议划分、数据封装,以及报文、报文段、分组、帧、数据报,这些内容,如果想要详细了解,则看计算机网络对应教材,此处不再赘述。
想要在Java编程中使用到网络编程,则需要我们引入java.net包。java.net包实现为了实现对网络通讯的三种操作:地址控制、端口控制、规则控制。其中,端口因为不需要太多操作,且完全由数字及IANA规定了使用规则,Java中就只需要实现地址控制和规则操作了。
InetAddress系列IP地址类
java.net包中,用来描述IP地址的是InetAddress类和他的两个字累Inte4Address与Inet6Address。IP地址类主要被我们用于对IP地址信息的Java操作。常用来获取指定主机或IP地址的网络信息。如例:
该例就是对获取主机地址信息常用方法的一个类比应用。可以从其结果和参数上,看出各个方法的着重点。
java.net包中,用于描述传输规则的类分为两种类型方向,UDP和TCP。
UDP:不可靠,即时性,面向无连接,每隔数据报大小限制在64K之内。
TCP:“三次握手、四次挥手”式连接,可靠,效率低、非即时,连接形成传输通道。
所以,即时通讯常用UDP,以保证即时性。但是如一些下载文件之类的通信,常用TCP以保证完整性。
这两个网络规则的实现,避免不了要涉及到文件的传输和对应进程的定位。实现这种操作的基础就是Socket套接字服务。Socket套接字,计算机间通过套接字来实现端对端通信。简易定义Socket=(IP地址,端口号)。
我们首先从UDP入手。
UDP服务
UDP的套接字类包括:DatagramSocket和DatagramPacket。UDP的收发服务及数据传输,在Java中就是由这两个类来实现的。我们通过实例来说明具体步骤。
文件发送端步骤演示:
文件接收端步骤演示:
当然,想要发送成功,就如上面两例演示所展示,必须得先开接收端。有了接收端,发送端的数据才不会丢包。
实际生活中,接收端一般都是24小时运行的。一般情况下,作为接收端,我们会将它内部接受信号部分(即除去UDP服务开启部分),放入一个while条件循环当中。这样是为了保证接收端能够不断的接收到客户端信息。
TCP服务
TCP的套接字类包括:Socket和SeverSocket。从字面上不难看出TCP的类是以客户端、服务端进行分类的。客户端和服务端作为两个端点,只要建立好并完成连接,就可以通讯实现数据传输。
图9.TCP客户端与服务端数据传输示意图
我们通过实例来说明上图中的客户端与服务端的信息传递具体步骤。下面这则实例,我们描述了从客户端向服务端发送数据的过程。
客户端文件发送步骤演示:
服务端文件接收步骤演示:
上例中,我们只演示了从客户端向服务端发送信息的情况。接下来为我们来演示一下,当服务端接受到请求后,向客户端发送数据的过程。
TCP客户端代码:
TCP服务端代码:
从上面的TCP实例中,我们不难看出。实际应用中TCP连接所对应服务端,也可以主动关闭客户端和自身之间的连接。而实际应用中,我们的确加入了时间判定用于关闭超时的无用连接。这样的特征是和TCP“三次握手、四次挥手”的特点相对应的。
需要注意的是,TCP是一种面向连接的服务。这就决定了该服务的服务端和客户端是有先后顺序的。服务端早于客户端启动。服务端在前,客户端在后。且,当一方数据传输结束后,我们需要关闭输出流。使用对应Socket对象来调用shutdownOutput()方法来实现。
当然,我们也可以通过这种方式来建立服务器,用浏览器作为客户端访问。Tomcat服务器,就是这样的一种封装了SeverSocket的Java服务器软件,它具体的实现过程都是一样的。Windows当中也提供了telnet这个CMD命令,来实现命令控制台直连服务器,这种访问形式。题外话,不难想到,Windows这样的命令也间接的反映了它安全性的问题。
我们访问网页的时候常常要用到URL统一标示语言,来定位访问的网站的IP、端口,和位置路径。在没有封装URL类对象之前,我们常用下面这种手动方法,来进行分割提取信息。这也是URL类封装后的信息提取原理。
当人们发现这样做不利于程序封装,进而重新设立了URL类,来统一管理此类数据后。我们的网络地址数据提取,就变得容易了许多。通常情况下,我们常用的方法有:
String getFile():获取本URL的文件名;
String getHost():获取本URL的主机名;
String getPort():获取本URL的端口号;
String getPath():获取本URL的路径部分;
String getQuery():获取本URL的查询部;
String getProtocol():获取本URL的协议名;
URLConnection openConnection():返回本URL的一个远程对象的连接引用;
这些方法,能够帮助我们从URL对象中,获取我们所需的信息。要注意的是URLConnection类,本类将原本连接及一系列相关操作、信息,通过封装而将其升高到了应用层的层面上。这样做,简化了对应网络端对端连接的操作。由于Socket在URLConnection内部封装,URLConnection对象,不需要在结束时关闭本身。关闭操作由内部自动完成。同时,由于URLConnection是应用层类,它要求并实现了本身在输出数据的时候,会自动拆包。
除了openConnection方法外,URLConnection还提供了openStream方法。该方法能够直接返回输出流,其本身实际上是openConnection和getInputStream两者的组合。先调用方法openConnection,再调用方法getInputStream。
------- android培训、java培训、期待与您交流!
----------
----------
网络编程
在掌握了基本的程序编写技巧后,我们来看一下Java网络编程。在这部分总结之前,我们首先需要掌握一些计算机网络的学科知识,这里给出了部分主要内容的概述:
端口:为进程间通信提供必要标识的数据标识,我们称之为端口。它是计算机程序为了区分不同进程而创立的区别方式。因此,端口号只具有本地意义,对应主机间通讯,在某种情况下必须指明对应接受传输数据端口号。
端口号分为两种:服务端使用端口号、客户端使用端口号。
服务端使用端口号又分为:熟知端口号、登记端口号。
熟知端口号:0~1023,IANA,即互联网地址指派机构,将此类端口派给了TCP/IP协议的一些重要程序。
登记端口号:1024~49151,此类端口号为一些没有熟知端口号的应用程序使用。想要使用登记端口号,则必须在IANA登记才可使用。
客户端使用端口号:又被称为短暂端口号,因为此类端口号只在客户进程运行时才会动态的选择调用。当用户进程结束时,此类端口则会自动释放。便于其他进程使用。此类端口号并没有具体使用要求,一般在程序运行时,都会由系统分配,并回收。
端口的存在,另一点就是为直达进程的网际进程间通信,打下了条件。
除了端口之外,在网际数据传输上,我们根据实际情况将计算机网络体系结构分为一下两种模型。
图8.计算机网络体系结构图
本质上,这两种模型都是对同一种事物,即网络,的不同描述。我们这里的Java程序,主要运用到的是TCP/IP中传输层、网际层,这两层的协议。如果是Java-Web开发,则会涉及应用层的协议。具体协议划分、数据封装,以及报文、报文段、分组、帧、数据报,这些内容,如果想要详细了解,则看计算机网络对应教材,此处不再赘述。
想要在Java编程中使用到网络编程,则需要我们引入java.net包。java.net包实现为了实现对网络通讯的三种操作:地址控制、端口控制、规则控制。其中,端口因为不需要太多操作,且完全由数字及IANA规定了使用规则,Java中就只需要实现地址控制和规则操作了。
InetAddress系列IP地址类
java.net包中,用来描述IP地址的是InetAddress类和他的两个字累Inte4Address与Inet6Address。IP地址类主要被我们用于对IP地址信息的Java操作。常用来获取指定主机或IP地址的网络信息。如例:
import java.net.*; class MyIPTest { public static void main(String[] args) { //本地主机地址获取 InetAddress i =InetAddress.getLocalHost(); System.out.println(i.toString()); System.out.println("name:"+i.getHostName()); System.out.println("address:"+i.getHostAddress()); //获取目标IP对应主机地址信息 InetAddress i2 =InetAddress.getByName("8.8.8.8"); System.out.println("name:"+i.getHostName()); System.out.println("address:"+i.getHostAddress()); //获取目标主机名所对应的一系列IP地址 InetAddress[] i3 =InetAddress.getAllByName("www.google.com"); for(int n = 0; n<i3.length();n++) { System.out.println("name:"+i3 .getHostName()); System.out.println("address:"+i .getHostAddress()); } } }
该例就是对获取主机地址信息常用方法的一个类比应用。可以从其结果和参数上,看出各个方法的着重点。
java.net包中,用于描述传输规则的类分为两种类型方向,UDP和TCP。
UDP:不可靠,即时性,面向无连接,每隔数据报大小限制在64K之内。
TCP:“三次握手、四次挥手”式连接,可靠,效率低、非即时,连接形成传输通道。
所以,即时通讯常用UDP,以保证即时性。但是如一些下载文件之类的通信,常用TCP以保证完整性。
这两个网络规则的实现,避免不了要涉及到文件的传输和对应进程的定位。实现这种操作的基础就是Socket套接字服务。Socket套接字,计算机间通过套接字来实现端对端通信。简易定义Socket=(IP地址,端口号)。
我们首先从UDP入手。
UDP服务
UDP的套接字类包括:DatagramSocket和DatagramPacket。UDP的收发服务及数据传输,在Java中就是由这两个类来实现的。我们通过实例来说明具体步骤。
文件发送端步骤演示:
import java.net.*; class UDP_sendDemo { public static void main(String[] args) { //1.通过DatagramSocket创立UDP服务 DatagramSocket UDPs = newDatagramSocket(); //2.确定传输数据,将其封入DatagramPacket对象中,进行传输前准备 byte[] buf = "This is an UDPpacket.".getBytes(); DatagramPacket UDPp = newDatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),7070); //3.通过开启的UDP服务,将数据发给指定接收方 UDPs.send(UDPp); //4.发送结束,关闭服务 UDPs.close(); } } /*当然,有发送就得有接受,没有给定接收方,这样的发送必然发生丢包。 */
文件接收端步骤演示:
import java.net.*; class UDP_receiveDemo { public static void main(String[] args) { //1.通过DatagramSocket创立UDP接收端点,并指定监听端口 DatagramSocket UDPs = newDatagramSocket(7070); //2.定义本地DatagramPacket对象用于存储接收数据,便于用其类封装的方法 byte[] buf = new byte[1024]; DatagramPacket UDPp = newDatagramPacket(buf,buf.length); //3.通过UDP服务,接收数据 UDPs.receive(UDPp); //4.通过DatagramPacket类封装方法获取数据 String ip =UDPp.getAddress().getHostAddress(); String res =UDPp.getAddress().getHostName(); String data = newString(UDPp.getData(),0,UDPp.getLength()); int port = UDPp.getPort(); //此处获取的端口号为发送端定义的端口号,该号由发送端决定 System.out.println(res+"::"+ip+"::"+port+"::"+data); //5.接收结束,关闭服务(可选操作) UDPs.close(); } } /*在定义接收端的时候,一般会为接收端指定一个和发送端端口对应的端口。用于分辨 对应接收信息。receive方法是一个阻塞式方法,如果没有接收到所求数据,则程序 在该位置被阻塞。直到获取所需信息。 另一个需要注意的是,如果没有指定端口号,不论是发送端还是接收端,系统都会为 未指定端口的进程分配一个系统端口。该端口号,数字上是随程序顺序递增的。通常, 为我们为了保证程序收发的正常进行,会为接收端指定端口号。我们也可用一样的方 法为发送端指定端口号。 */
当然,想要发送成功,就如上面两例演示所展示,必须得先开接收端。有了接收端,发送端的数据才不会丢包。
实际生活中,接收端一般都是24小时运行的。一般情况下,作为接收端,我们会将它内部接受信号部分(即除去UDP服务开启部分),放入一个while条件循环当中。这样是为了保证接收端能够不断的接收到客户端信息。
TCP服务
TCP的套接字类包括:Socket和SeverSocket。从字面上不难看出TCP的类是以客户端、服务端进行分类的。客户端和服务端作为两个端点,只要建立好并完成连接,就可以通讯实现数据传输。
图9.TCP客户端与服务端数据传输示意图
我们通过实例来说明上图中的客户端与服务端的信息传递具体步骤。下面这则实例,我们描述了从客户端向服务端发送数据的过程。
客户端文件发送步骤演示:
import java.net.*; import java.io.*; class TCP_clientDemo { public static void main(String[] args) { //1.建立客户端socket服务,指定服务端IP和对应端口 Socket client = newSocket("8.8.8.8",9920); //2.建立输出流,发送需求数据 OutputStream out =client.getOutputStream(); out.write("This is a TCPdata".getBytes()); //3.任务完成,客户端关闭 client.close(); } }
服务端文件接收步骤演示:
import java.net.*; import java.in.*; class TCP_serverDemo { public static void main(String[] args) { //1.建立服务端socket服务,并设立监听端口 ServerSocket server = newServerSocket(9220); //2.通过服务端SeverSocket类中的accept方法,获取客户端对象 Socket sc = server.accept(); //3.建立输入流,读取客户端发送信息 { InputStream in =sc.getInputStream(); byte[] buf = newbyte[1024]; int length = in.read(buf); String s = newString(buf,0,length); System.out.println(s); } //4.接收结束,关闭客户端 sc.close(); //服务端关闭可规定在一定时间之后。 //5.关闭服务端(可选操作) server.close(); } }
上例中,我们只演示了从客户端向服务端发送信息的情况。接下来为我们来演示一下,当服务端接受到请求后,向客户端发送数据的过程。
TCP客户端代码:
import java.net.*; import java.io.*; class TCP_client_receiveDemo { public static void main(String[] args) { Socket client = newSocket("8.8.8.8",9980); OutputStream out =client.getOutputStream(); out.write("This is aboutgeting answers.".getBytes()); //关闭客户端输出流: client.shutdownOutput(); //客户端接受服务端文件: InputStream in =client.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println("client_request::"+newString(buf,0,len)); client.close(); } }
TCP服务端代码:
import java.net.*; import java.io.*; class TCP_server_sendDemo { public static void main(String[] args) { ServerSocket server = newServerSocket(9980); Socket s = server.accept(); String ip =s.getInetAddress().getHostAddress(); InputStream in =s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(ip+"::"+newString(buf,0,len)); //服务端发送文件给客户端: OutputStream out =s.getOutputStream(); out.write("Request_Datapackage".getBytes()); s.close(); } }
从上面的TCP实例中,我们不难看出。实际应用中TCP连接所对应服务端,也可以主动关闭客户端和自身之间的连接。而实际应用中,我们的确加入了时间判定用于关闭超时的无用连接。这样的特征是和TCP“三次握手、四次挥手”的特点相对应的。
需要注意的是,TCP是一种面向连接的服务。这就决定了该服务的服务端和客户端是有先后顺序的。服务端早于客户端启动。服务端在前,客户端在后。且,当一方数据传输结束后,我们需要关闭输出流。使用对应Socket对象来调用shutdownOutput()方法来实现。
当然,我们也可以通过这种方式来建立服务器,用浏览器作为客户端访问。Tomcat服务器,就是这样的一种封装了SeverSocket的Java服务器软件,它具体的实现过程都是一样的。Windows当中也提供了telnet这个CMD命令,来实现命令控制台直连服务器,这种访问形式。题外话,不难想到,Windows这样的命令也间接的反映了它安全性的问题。
我们访问网页的时候常常要用到URL统一标示语言,来定位访问的网站的IP、端口,和位置路径。在没有封装URL类对象之前,我们常用下面这种手动方法,来进行分割提取信息。这也是URL类封装后的信息提取原理。
String url ="http://192.168.1.1:8080/Requto/default.html" int i1 = url.indexOf("//")+2; int i2 =url.indexOf("/",i1); String str =url.substring(i1,i2); String[] buf =str.split(":"); String host = buf[0]; int port =Integer.parseInt(buf[1]); String path =url.substring(i2);
当人们发现这样做不利于程序封装,进而重新设立了URL类,来统一管理此类数据后。我们的网络地址数据提取,就变得容易了许多。通常情况下,我们常用的方法有:
String getFile():获取本URL的文件名;
String getHost():获取本URL的主机名;
String getPort():获取本URL的端口号;
String getPath():获取本URL的路径部分;
String getQuery():获取本URL的查询部;
String getProtocol():获取本URL的协议名;
URLConnection openConnection():返回本URL的一个远程对象的连接引用;
这些方法,能够帮助我们从URL对象中,获取我们所需的信息。要注意的是URLConnection类,本类将原本连接及一系列相关操作、信息,通过封装而将其升高到了应用层的层面上。这样做,简化了对应网络端对端连接的操作。由于Socket在URLConnection内部封装,URLConnection对象,不需要在结束时关闭本身。关闭操作由内部自动完成。同时,由于URLConnection是应用层类,它要求并实现了本身在输出数据的时候,会自动拆包。
除了openConnection方法外,URLConnection还提供了openStream方法。该方法能够直接返回输出流,其本身实际上是openConnection和getInputStream两者的组合。先调用方法openConnection,再调用方法getInputStream。
------- android培训、java培训、期待与您交流!
----------
相关文章推荐
- 黑马程序员--10.网络编程--02.【网络传输三要素在Java中的体现】【TCP和UDP概念】【Socket基本概念】
- 黑马程序员_毕向东JAVA基础_网络编程(概述&UDP&TCP)
- 黑马程序员_网络编程TCP/UDP原理及其流程比较(java)
- 黑马程序员--Java基础学习之网络编程(TCP、UDP、Socket、模拟发送和接收数据)
- 黑马程序员_java基础13网络编程 TCP和DNS
- 『黑马程序员』---java--网络编程--网络编程概念+UDP基础
- 黑马程序员——java网络编程中的传输协议:UDP和TCP
- 黑马程序员——Java网络编程(TCP和UDP)
- 黑马程序员_java网络编程——UDP传输和TCP传输
- 黑马程序员--java基础--网络编程(UDP和TCP)
- 黑马程序员-------Java笔记--------网络编程(UDP与TCP基本步骤)
- 网络编程_概念_网络_端口_URL_TCP_UDPJAVA184
- 网络编程-概念及UDP、TCP连接
- java基础学习网络编程之UDP和TCP协议 十四 -3
- 黑马程序员-网络编程概述-网络模型-UDP-TCP
- Java中的TCP/UDP网络通信编程
- 【java编程】tcp/udp——Socket网络编程部分
- Java_网络编程_UDP与TCP的区别
- java网络编程基础夯实06-TCP,UDP,HTTP,Socket简介