20145215《Java程序设计》第10周学习总结

20145215《Java程序设计》第十周学习总结

教材学习内容总结

网络编程

网络概述

  • 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据。程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴。在发送和接收数据时,大部分的程序设计语言都设计了专门的API实现这些功能,程序员只需要调用即可。
  • 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出现,所以在实际的开发中网络编程技术获得了大量的使用。
  • 计算机网络概述:
  1. 按照计算机网络的定义,通过一定的物理设备将处于不同位置的计算机连接起来组成的网络,这个网络中包含的设备有:计算机、路由器、交换机等等。
  2. 为了能够方便的识别网络上的每个设备,网络中的每个设备都会有一个唯一的数字标识,这个就是IP地址。在计算机网络中,现在命名IP地址的规定是IPv4协议,每个接入网络的计算机都拥有唯一的IP地址,这个IP地址可能是固定的,也可以是动态的。
  3. 域名:例如sohu.com,一个IP地址可以对应多个域名,一个域名只能对应一个IP地址。
  4. DNS服务器是在实际传输数据以前将域名转换为IP地址的服务器,当用户在浏览器输入域名时,浏览器首先请求DNS服务器,将域名转换为IP地址,然后将转换后的IP地址反馈给浏览器,然后再进行实际的数据传输。
  5. 端口是为了让一个计算机可以同时运行多个网络程序,在同一个计算机中每个程序对应唯一的端口,这样一个计算机上就可以通过端口区分发送给每个端口的数据了,换句话说,也就是一个计算机上可以并发运行多个网络程序,而不会在互相之间产生干扰。
  • 网络编程概述:
  1. 网络通讯基于“请求-响应”模型,在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。
  2. 网络编程中常见的两种结构:C/S结构和B/S结构。C/S结构即客户端/服务器结构,在开发时需要分别开发客户端和服务器端,这种结构的优势在于由于客户端是专门开发的,可以根据需要实现各种效果,它的缺点在于通用性查,维护压力大。B/S结构即浏览器/服务器结构,在开发时只需要开发服务器端即可,这种结构的优势在于开发的压力比较小,不需要维护客户端,但是览器的限制比较大,表现力不强。
  3. P2P程序是一种特殊的程序,应该一个P2P程序中既包含客户端程序,也包含服务器端程序,例如BT,使用客户端程序部分连接其它的种子(服务器端),而使用服务器端向其它的BT客户端传输数据。
  4. 在实际进行数据交换时,为了让接收端理解该数据,计算机比较笨,什么都不懂的,那么就需要规定该数据的格式,这个数据的格式就是协议。
  • 网络通讯方式:
  1. 网络通讯的方式主要有两种:TCP(传输控制协议)方式和UDP(用户数据报协议)方式。
  2. TCP方式需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。
  3. 重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。

网络编程技术

  • 客户端网络编程步骤:
  1. 建立网络连接:客户端网络编程的第一步都是建立网络连接。在建立网络连接时需要指定连接到的服务器的IP地址和端口号,建立完成以后,会形成一条虚拟的连接,后续的操作就可以通过该连接实现数据交换了。
  2. 交换数据:连接建立以后,就可以通过这个连接交换数据了。交换数据严格按照请求响应模型进行,由客户端发送一个请求数据到服务器,服务器反馈一个响应数据给客户端,如果客户端不发送请求则服务器端就不响应。
  3. 关闭网络连接:在数据交换完成以后,关闭网络连接,释放程序占用的端口、内存等系统资源,结束网络编程。
  • 服务器端网络编程步骤:
  1. 监听端口:服务器端属于被动等待连接,所以服务器端启动以后,不需要发起连接,而只需要监听本地计算机的某个固定端口即可,这个端口就是服务器端开放给客户端的端口,服务器端程序运行的本地计算机的IP地址就是服务器端程序的IP地址。
  2. 获得连接:当客户端连接到服务器端时,服务器端就可以获得一个连接,这个连接包含客户端的信息,例如客户端IP地址等等,服务器端和客户端也通过该连接进行数据交换,一般在服务器端编程中,当获得连接时,需要开启专门的线程处理该连接,每个连接都由独立的线程实现。
  3. 交换数据:服务器端通过获得的连接进行数据交换。服务器端的数据交换步骤是首先接收客户端发送过来的数据,然后进行逻辑处理,再把处理以后的结果数据发送给客户端。简单来说,就是先接收再发送,这个和客户端的数据交换数序不同。
  4. 关闭连接:当服务器程序关闭时,需要关闭服务器端,通过关闭服务器端使得服务器监听的端口以及占用的内存可以释放出来,实现了连接的关闭。
  • Java网络编程技术:
  1. 一个基础的网络类——InetAddress类。该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。
  2. InetAddressDemo.java代码运行示例如下:

TCP编程

  • TCP客户端编程:
  1. 在客户端网络编程中,首先需要建立连接,在Java API中以java.net.Socket类的对象代表网络连接,所以建立客户端网络连接,也就是创建Socket类型的对象,该对象代表网络连接,示例如下:
Socket socket = new Socket(“192.168.1.103”,10000);
  1. 连接建立之后,然后按照“请求-响应”模型进行网络数据交换,在Java语言中,数据传输功能由Java IO实现,也就是说只需要从连接中获得输入流和输出流即可,然后将需要发送的数据写入连接对象的输出流中,在发送完成以后从输入流中读取数据即可:
OutputStream os = socket1.getOutputStream();   //获得输出流
InputStream is = socket1.getInputStream();     //获得输入流
  1. 最后当数据交换完成以后,关闭网络连接,释放网络连接占用的系统端口和内存等资源,完成网络操作:
socket.close();
  1. SimpleSocketClient.java代码运行示例如下:
  • TCP服务器编程:
  1. 在服务器端程序编程中,由于服务器端实现的是被动等待连接,所以服务器端编程的第一个步骤是监听端口,也就是监听是否有客户端连接到达:
ServerSocket ss = new ServerSocket(10000);
  1. 然后是获得连接,当有客户端连接到达时,建立一个和客户端连接对应的Socket连 接对象,从而释放客户端连接对于服务器端端口的占用:
Socket socket = ss.accept();
  1. 连接获得以后,后续的编程就和客户端的网络编程类似了,这里获得的Socket类型的连接就和客户端的网络连接一样了,只是服务器端需要首先读取发送过来的数据,然后进行逻辑处理以后再发送给客户端,也就是交换数据的顺序和客户端交换数据的步骤刚好相反。
  2. 最后,在服务器端通信完成以后,关闭服务器端连接:
ss.close();
  1. SimpleSocketServer.java代码运行示例如下:
  • 复用连接客户端:
  1. 建立连接以后,将数据交换的逻辑写到一个循环中,这样只要循环不结束则连接就不会被关闭,可以用这样的方式来实现建立一次连接,进行多次数据交换。
  2. MulSocketClient.java代码运行示例如下:
  • 复用连接服务器:
  1. 按照客户端实现的逻辑,也可以复用服务器端的连接,实现的原理也是将服务器端的数据交换逻辑写在循环中。
  2. MulSocketServer.java代码运行示例如下:
  • 多客户端的服务器:
  1. 一个服务器端一般都需要同时为多个客户端提供通讯,当服务器端接收到一个连接时,启动一个专门的线程处理和该客户端的通讯,这样就可以支持多个客户端。
  2. MulThreadSocketServer类实现服务器端控制,实现接收客户端连接,然后开启专门的逻辑线程处理该连接,LogicThread类实现对于一个客户端连接的逻辑处理,将处理的逻辑放置在该类的run方法中。

UDP编程

  • 使用UDP方式无需建立专用的虚拟连接,由于无需建立专用的连接,所以对于服务器的压力要比TCP小很多,但是使用该种方式最大的不足是传输不可靠,所以在网络编程中,必须要求可靠传输的信息一般使用TCP方式实现,一般的数据才使用UDP方式实现。
  • UDP方式的网络编程也在Java语言中获得了良好的支持,由于其在传输数据的过程中不需要建立专用的连接等特点,所以在Java API中设计的实现结构和TCP方式不太一样。当然,需要使用的类还是包含在java.net包中。
  • 在Java API中,实现UDP方式的编程,包含客户端网络编程和服务器端网络编程,主要由两个类实现:
  1. DatagramSocket:DatagramSocket实现的是发送数据时的发射器,以及接收数据时的监听器的角色。类比于TCP中的网络连接,该类既可以用于实现客户端连接,也可以用于实现服务器端连接。
  2. DatagramPacket:类的对象代表网络中交换的数据。在UDP方式的网络编程中,无论是需要发送的数据还是需要接收的数据,都必须被处理成DatagramPacket类型的对象,该对象中包含发送到的地址、发送到的端口号以及发送的内容等。
  • UDP客户端编程:
  1. UDP方式的建立连接和TCP方式不同,只需要建立一个连接对象即可,不需要指定服务器的IP和端口号码,示例如下:
DatagramSocket ds = new DatagramSocket();
  1. 使用UDP在发送数据时,需要将需要发送的数据内容首先转换为byte数组,然后将数据内容、服务器IP和服务器端口号一起构造成一个DatagramPacket类型的对象,这样数据的准备就完成了,发送时调用网络连接对象中的send方法发送该对象即可,同样,UDP方式在进行网络通讯时,也遵循“请求-响应”模型。
  2. UDP的接收数据是这样实现的:首先构造一个数据缓冲数组,该数组用于存储接收的服务器端反馈数据,该数组的长度必须大于或等于服务器端反馈的实际有效数据的长度。然后以该缓冲数组为基础构造一个DatagramPacket数据包对象,最后调用连接对象的receive方法接收数据即可。接收到的服务器端反馈数据存储在DatagramPacket类型的对象内部。
  3. UDP关闭连接,使用连接对象中的close方法即可:
ds.close();
  1. SimpleUDPClient.java代码运行示例如下:
  • UDP服务器编程:
  1. 基本上也与TCP服务器编程类似,不过使用的对象不同
  2. SimpleUDPServer.java代码运行示例如下:
  • UDP方式的网络编程由于不建立虚拟的连接,所以在实际使用时和TCP方式存在很多的不同,最大的一个不同就是“无状态”。该特点指每次服务器端都收到信息,但是这些信息和连接无关,换句话说,也就是服务器端只是从信息是无法识别出是谁发送的,这样就要求发送信息时的内容需要多一些.
  • 多次发送客户端:实现的原理和TCP方式类似,在客户端将数据的发送和接收放入循环中,而服务器端则将接收到的每个数据包启动一个专门的线程进行处理。
  • 并发处理数据包的服务器:用一个循环来接收客户端发送过来的数据包,当接收到数据包以后启动一个LogicThread线程处理该数据包。这样服务器端就可以实现同时处理多个数据包了。

网络协议

  • 网络协议是指对于网络中传输的数据格式的规定,其实质也是客户端程序和服务器端程序对于数据的一种约定。
  • 对于同一个网络程序来说,一般都会涉及到两个网络协议格式:客户端发送数据格式和服务器端反馈数据格式,在实际设计时,需要一一对应。
  • 客户端程序需要完成的处理为:
  1. 客户端发送协议格式的生成
  2. 服务器端反馈数据格式的解析
  • 服务器端程序需要完成的处理为:
  1. 服务器端反馈协议格式的生成
  2. 客户端发送协议格式的解析

质数判别实例

  • 客户端程序功能:
  1. 接收用户控制台输入
  2. 断输入内容是否合法
  3. 按照协议格式生成发送数据
  4. 发送数据
  5. 接收服务器端反馈
  6. 解析服务器端反馈信息,并输出
  • 服务器端程序功能:
  1. 接收客户端发送数据
  2. 按照协议格式解析数据
  3. 判断数字是否是质数
  4. 根据判断结果,生成协议数据
  5. 将数据反馈给客户端
  • 客户端发送协议格式:
  1. 将用户输入的数字转换为字符串,再将字符串转换为byte数组即可。
  2. 例如用户输入16,则转换为字符串“16”,使用getBytes转换为byte数组。
  3. 客户端发送“quit”字符串代表结束连接
  • 服务器端发送协议格式:
  1. 反馈数据长度为1个字节。数字0代表是质数,1代表不是质数,2代表协议格式错误。
  2. 例如客户端发送数字12,则反馈1,发送13则反馈0,发送0则反馈2。
  • 客户端运行示例如下:

  • 服务器运行示例如下:

猜数字小游戏

  • 客户端运行示例如下:

  • 服务器运行示例如下:

代码调试中遇到的问题及解决过程

端口号被占用了,改了一个端口号就好了。

心得体会

本周的学习是网络编程的一个入门,以前一谈到网络编程总感觉有些高深莫测,其实当自己真正接触到的时候才会发现并没有想象中的那么难理解,当然,现在我们还只是接触到了网络编程的基础,在以后的学习中,难度肯定会不断增加,但是只要我们肯花时间去钻研,即使中途花费的时间再多,也是值得的。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时 编写了Hello Java代码
第一周 100/100 2/2 12/12 编写了Hello Java代码
第二周 200/300 2/4 15/27 理解了printf和println的区别
第三周 450/750 1/5 22/49 对对象有了更深层次的理解
第四周 869/1619 1/6 28/77 对对象的三大特征有了更全面的认识
第五周 1123/2742 1/7 25/102 学会了异常处理
第六周 863/3605 2/9 30/132 理解了线程
第七周 505/4110 2/11 28/160 掌握了日期和时间的运用
第八周 490/4600 2/13 26/186 掌握了git托管的节奏
第九周 591/5191 2/15 30/216 初步学会使用MySQL
第十周 1169/6360 3/18 33/249 掌握网络编程的基础

【附1】本周学习的代码已经成功托管,截图如下:

【附2】利用wc统计代码行数,截图如下:

参考资料

posted @ 2016-05-08 18:39  L.X.M  阅读(341)  评论(1编辑  收藏  举报