20145226夏艺华 《Java程序设计》第10周学习总结
教材学习内容总结
学习目标
-
了解计算机网络基础
-
掌握Java Socket编程
网络编程
网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据。程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴。在发送和接收数据时,大部分的程序设计语言都设计了专门的API实现这些功能,程序员只需要调用即可。
网络概述
按照计算机网络的定义,通过一定的物理设备将处于不同位置的计算机连接起来组成的网络,这个网络中包含的设备有:计算机、路由器、交换机等等。路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤、网线等连接将设备连接起来,从而形成了一张巨大的计算机网络。网络最主要的优势在于共享:共享设备和数据。
了能够方便的识别网络上的每个设备,网络中的每个设备都会有一个唯一的数字标识,这个就是IP地址。在计算机网络中,现在命名IP地址的规定是IPv4协议,该协议规定每个IP地址由4个0-255之间的数字组成,,每个接入网络的计算机都拥有唯一的IP地址,这个IP地址可能是固定的,也可以是动态的,无论以何种方式获得或是否是固定的,每个计算机在联网以后都拥有一个唯一的合法IP地址。
但是由于IP地址不容易记忆,所以为了方便记忆,有创造了另外一个概念——域名(Domain Name)。一个IP地址可以对应多个域名,一个域名只能对应一个IP地址。
网络编程就是两个或多个程序之间的数据交换,和普通的单机程序相比,网络程序最大的不同就是需要交换数据的程序运行在不同的计算机上,这样就造成了数据交换的复杂。
在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。
网络编程的结构包含两种,分别为:客户端/服务器结构(C/S结构)和浏览器/服务器结构(B/S结构)。 使用C/S结 构的程序,在开发时需要分别开发客户端和服务器端,优势是表现力丰富。但是这种结构也存在着很多不足,例如通用性差,也就是说一种程序的客户端只能和对应的服务器端通讯,而不能和其它服务器端通讯,在实际维护时,也需要维护专门的客户端和服务器端,维护的压力比较大。使用B/S结构的程序,在开发时只需要开发服务器端即可,这种结构的优势在于开发的压力比较小,不需要维护客户端。但是这种结构也存在着很多不足,例如浏览器的限制比较大,表现力不强,无法进行系统级操作等。
P2P程序是一种特殊的程序,一个P2P程序中既包含客户端程序,也包含服务器端程序。
协议在网络编程中就是确定网络中传输的数据格式。
在现有的网络中,网络通讯的方式主要有两种:TCP(传输控制协议)方式以及UDP(用户数据报协议)方式。在网络通讯中,TCP方式在网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式在进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。
在网络编程中,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。由于TCP需要建立专用的虚拟连接以及确认传输是否正确,所以使用TCP方式的速度稍微慢一些,而且传输时产生的数据量要比UDP稍微大一些。
网络编程技术
(一) 客户端网络编程步骤
客户端(Client)是指网络编程中首先发起连接的程序,客户端一般实现程序界面和基本逻辑实现,客户端的编程主要由三个步骤实现:步骤一是建立网络连接,在建立网络连接时需要指定连接到的服务器的IP地址和端口号,建立完成以后,会形成一条虚拟的连接,后续的操作就可以通过该连接实现数据交换了;步骤二是交换数据,交换数据严格按照请求响应模型进行,由客户端发送一个请求数据到服务器,服务器反馈一个响应数据给客户端,如果客户端不发送请求则服务器端就不响应;步骤三是关闭网络连接,在数据交换完成以后,关闭网络连接,释放程序占用的端口、内存等系统资源,结束网络编程。其中在实际实现时,步骤二会出现重复。
(二) 服务器端网络编程步骤
服务器端(Server)是指在网络编程中被动等待连接的程序,服务器端一般实现程序的核心逻辑以及数据存储等核心功能。服务器端的编程主要由四个步骤实现:步骤一是监听端口,服务器端属于被动等待连接,所以服务器端启动后只需要监听本地计算机的某个固定端口即可,该端口就是服务器端开放给客户端的端口;步骤二是获得连接,当客户端连接到服务器端时,服务器端就可以获得一个连接,这个连接包含客户端的信息,服务器端和客户端也通过该连接进行数据交换;步骤三是交换数据,服务器端的数据交换步骤是首先接收客户端发送过来的数据,然后进行逻辑处理,再把处理以后的结果数据发送给客户端;步骤四是关闭连接,通过关闭服务器端使得服务器监听的端口以及占用的内存可以释放出来,实现了连接的关闭。
(三) Java网络编程技术
在Java中和网络编程有关的基本API位于java.net包中,该包中包含了基本的网络编程实现,该包是网络编程的基础。该包中既包含基础的网络编程类,也包含封装后的专门处理WEB相关的处理类。其中一个基础的网络类是InetAddress类,该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。InetAddressDemo.java操作InetAddress对象,最后运行的结果如下所示:
(四) TCP编程
TCP方式的网络通讯是指在通讯的过程中保持连接,只需要建立一次网络连接,就可以多次传输数),在实际的网络编程中传输可靠,如果发送的一方发送的数据接收方觉得有问题,则网络底层会自动要求发送方重发,直到接收方收到为止。
在Java语言中,对于TCP方式的网络编程提供了良好的支持,在实现时,以java.net.Socket类代表客户端连接,以java.net.ServerSocket类代表服务器端连接。在进行网络编程时,底层网络通讯的细节已经实现了比较高的封装,所以在程序员实际编程时,只需要指定IP地址和端口号码就可以建立连接了。下面分别介绍一下在Java语言中客户端和服务器端的实现步骤。
客户端网络编程
- 首先需要建立连接,在Java API中以java.net.Socket类的对象代表网络连接,所以建立客户端网络连接,也就是创建Socket类型的对象,该对象代表网络连接,具体如下:
Socket socket1 = new Socket(“192.168.1.103”,10000);
Socket socket2 = new Socket(“www.sohu.com”,80);
socket1实现的是连接到IP地址是192.168.1.103的计算机的10000号端口,而socket2实现的是连接到域名是www.sohu.com的计算机的80号端口,至于底层网络如何实现建立连接,对于程序员来说是完全透明的。如果建立连接时,本机网络不通,或服务器端程序未开启,则会抛出异常。
- 数据传输功能在Java语言中由Java IO实现,也就是说只需要从连接中获得输入流和输出流即可,然后将需要发送的数据写入连接对象的输出流中,在发送完成以后从输入流中读取数据即可。具体如下:
OutputStream os = socket1.getOutputStream(); //获得输出流
InputStream is = socket1.getInputStream(); //获得输入流
- 关闭网络连接,释放网络连接占用的系统端口和内存等资源,完成网络操作,具体如下:
socket1.close();
服务器网络编程
- 服务器端编程的第一个步骤是监听端口,也就是监听是否有客户端连接到达。实现服务器端监听的代码为:
ServerSocket ss = new ServerSocket(10000);
该代码实现的功能是监听当前计算机的10000号端口,如果在执行该代码时,10000号端口已经被别的程序占用,那么将抛出异常。否则将实现监听。
- 服务器端编程的第二个步骤是获得连接。当有客户端连接到达时,建立一个和客户端连接对应的Socket连 接对象,从而释放客户端连接对于服务器端端口的占用。实现获得连接的代码是:
Socket socket = ss.accept();
-
服务器端编程的第二个步骤是数据交换。服务器端需要首先读取发送过来的数据,然后进行逻辑处理以后再发送给客户端,也就是交换数据的顺序和客户端交换数据的步骤刚好相反。这部分的内容和客户端很类似.
-
最后,在服务器端通信完成以后,关闭服务器端连接。实现的代码为:
ss.close();
(五) 复用Socket连接
建立连接以后,将数据交换的逻辑写到一个循环中,这样只要循环不结束则连接就不会被关闭。
(六) 服务器端支持多个客户端同时工作
当服务器端接收到一个连接时,启动一个专门的线程处理和该客户端的通讯。按照这个思路,服务端程序将由两个部分组成,MulThreadSocketServer类实现服务器端控制,实现接收客户端连接,然后开启专门的逻辑线程处理该连接,LogicThread类实现对于一个客户端连接的逻辑处理,将处理的逻辑放置在该类的run方法中。
线程池(Thread pool)是池技术的一种,就是在程序启动时首先把需要个数的线程对象创建好,当客户端连接到达时从池中取出一个已经创建完成的线程对象使用即可。当客户端连接关闭以后,将该线程对象重新放入到线程池中供其它的客户端重复使用,这样可以提高程序的执行速度,优化程序对于内存的占用等。
(七) UDP方式的网络编程
UDP(User Datagram Protocol),中文意思是用户数据报协议,使用该种方式无需建立专用的虚拟连接,由于无需建立专用的连接,所以对于服务器的压力要比TCP小很多,也是一种常见的网络编程方式。但是使用该种方式最大的不足是传输不可靠。
DatagramSocket类实现“网络连接”,包括客户端网络连接和服务器端网络连接。因为需要发送和接收数据,所以需要网络连接,DatagramSocket实现的就是发送数据时的发射器,以及接收数据时的监听器的角色。类比于TCP中的网络连接,该类既可以用于实现客户端连接,也可以用于实现服务器端连接。
DatagramPacket类实现对于网络中传输的数据封装,该类的对象代表网络中交换的数据。在UDP方式的网络编程中,无论是需要发送的数据还是需要接收的数据,都必须被处理成DatagramPacket类型的对象,该对象中包含发送到的地址、发送到的端口号以及发送的内容等。
客户端网络编程
- UDP方式的建立连接和TCP方式不同,只需要建立一个连接对象即可,不需要指定服务器的IP和端口号码。具体如下:
DatagramSocket ds = new DatagramSocket();
- 在发送数据时,需要将需要发送的数据内容首先转换为byte数组,然后将数据内容、服务器IP和服务器端口号一起构造成一个DatagramPacket类型的对象,发送时调用网络连接对象中的send方法发送该对象即可。
String s = “Hello”;
String host = “127.0.0.1”;
int port = 10001;
//将发送的内容转换为byte数组
byte[] b = s.getBytes();
//将服务器IP转换为InetAddress对象
InetAddress server = InetAddress.getByName(host);
//构造发送的数据包对象
DatagramPacket sendDp = new DatagramPacket(b,b.length,server,port);
//发送数据
ds.send(sendDp);
- 首先构造一个数据缓冲数组,该数组用于存储接收的服务器端反馈数据,该数组的长度必须大于或等于服务器端反馈的实际有效数据的长度。然后以该缓冲数组为基础构造一个DatagramPacket数据包对象,最后调用连接对象的receive方法接收数据即可。
//构造缓冲数组
byte[] data = new byte[1024];
//构造数据包对象
DatagramPacket received = new DatagramPacket(data,data.length);
//接收数据
ds.receive(receiveDp);
//输出数据内容
byte[] b = receiveDp.getData(); //获得缓冲数组
int len = receiveDp.getLength(); //获得有效数据长度
String s = new String(b,0,len);
System.out.println(s);
- 虽然UDP方式不建立专用的虚拟连接,但是连接对象还是需要占用系统资源,所以在使用完成以后必须关闭连接。关闭连接使用连接对象中的close方法即可。
ds.close();
服务器端网络编程
UDP方式网络编程的服务器端实现和TCP方式的服务器端实现类似,也是服务器端监听某个端口,然后获得数据包,进行逻辑处理以后将处理以后的结果反馈给客户端,最后关闭网络连接。
- 建立一个连接,该连接监听某个端口,具体实现如下:
DatagramSocket ds = new DatagramSocket(10010);
-
服务器端就开始接收客户端发送过来的数据,其接收的方法和客户端接收的方法类似,其中receive方法的作用类似于TCP方式中accept方法的作用,该方法也是一个阻塞方法,其作用是接收数据。
-
接收到客户端发送过来的数据以后,服务器端对该数据进行逻辑处理,然后将处理以后的结果再发送给客户端.服务器端需要获得客户端的IP和客户端使用的端口号,可以从接收到的数据包中获得。
//获得客户端的IP
InetAddress clientIP = receiveDp.getAddress();
//获得客户端的端口号
Int clientPort = receiveDp.getPort();
- 当服务器端实现完成以后,关闭服务器端连接,实现的方式为调用连接对象的close方法。
网络协议
网络协议是指对于网络中传输的数据格式的规定。网络协议的实质也是客户端程序和服务器端程序对于数据的一种约定。网络协议就是一种格式上的约定,可以根据逻辑的需要约定出各种数据格式,在进行设计时一般遵循“简单、通用、容易解析”的原则进行。
在网络编程中,对于同一个网络程序来说,一般都会涉及到两个网络协议格式:客户端发送数据格式和服务器端反馈数据格式。客户端程序需要完成的处理为:客户端发送协议格式的生成;服务器端反馈数据格式的解析。服务器端程序需要完成的处理为:服务器端反馈协议格式的生成;客户端发送协议格式的解析。
对于程序员来说,在进行网络程序编写时,需要首先根据逻辑的需要设计网络协议格式,然后遵循协议格式约定进行协议生成和解析代码的编写,最后使用网络编程技术实现整个网络编程的功能。
而对于常见协议的格式,例如HTTP(Hyper Text Transfer Protocol,超文本传输协议)、FTP(File Transfer Protocol,文件传输协议),SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)等等,都有通用的规定,具体可以查阅相关的RFC文档。
对于一种网络程序来说,网络协议格式是该程序最核心的技术秘密,所以不能泄露。
教材学习种的问题和解决过程
代码调试中的问题和解决过程
1.在网络编程时很容易遇到端口占用问题,这种情况下,只需要修改端口号即可。
本周代码托管截图
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第二周 | 200/400 | 1/3 | 12/52 | |
预备作业 | 0/400 | 1/4 | 15/67 | |
第三周 | 500/900 | 1/5 | 10/77 | |
第四周 | 500/1500 | 1/6 | 15/92 | |
第五周 | 500/2000 | 1/7 | 20/112 | |
第六周 | 500/2500 | 2/9 | 20/132 | |
第七周 | 500/3000 | 2/11 | 30/162 | |
第八周 | 500/3500 | 2/13 | 20/182 | |
第九周 | 700/4200 | 2/15 | 30/212 | |
第十周 | 500/4700 | 2/17 | 40/252 |