首页 > 技术文章 > 20145201《Java程序设计》第十周学习总结

20145201lzx 2016-05-08 18:18 原文

教材学习内容总结

网络编程

  • 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据。

  • 程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴。

  • 在发送和接收数据时,大部分的程序设计语言都设计了专门的API实现这些功能,程序员只需要调用即可。

13.1网络概述

  • 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。

  • 每个计算机在联网以后都拥有一个唯一的合法IP地址,这个就是IP地址,就像每个手机号码一样。

  • 在计算机网络中,现在命名IP地址的规定是IPv4协议,该协议规定每个IP地址由4个0-255之间的数字组成。这个IP地址可能是动态的,也可能是固定的。

  • 为了方便记忆,有创造了另外一个概念域名(Domain Name)一个IP地址可以对应多个域名,一个域名只能对应一个IP地址。

  • DNS服务器:在网络中传输的数据,全部是以IP地址作为地址标识,所以在实际传输数据以前需要将域名转换为IP地址,实现这种功能的服务器称之为DNS服务器,也就是通俗的说法叫做域名解析。
    当DNS服务器正常工作时,使用IP地址或域名都可以很方便的找到计算机网络中的某个设备,例如服务器计算机。
    当DNS不正常工作时,只能通过IP地址访问该设备。

13.1. 2 网络编程概述

  • C/S结构:网络编程的结构被称作客户端/服务器结构,也叫做Client/Server结构。优点是表现力丰富,缺点是通用性差、维护的压力比较大。

  • B/S结构:使用浏览器作为客户端的结构被称作浏览器/服务器结构,也叫做Browser/Server结构。优点是开发的压力比较小,不需要维护客户端。缺点是限制比较大,表现力不强,无法进行系统级操作等。

C/S结构和B/S结构是现在网络编程中常见的两种结构,B/S结构其实也就是一种特殊的C/S结构。

•P2P程序:P2P程序中既包含客户端程序,也包含服务器端程序,是一种特殊的程序。一个P2P程序中既包含客户端程序,也包含服务器端程序。

•网络编程中最重要,也是最复杂的概念——协议(Protocol):在实际进行数据交换时,为了让接收端理解该数据,需要规定该数据的格式,这个数据的格式就是协议。

•如何来编写协议格式?只要按照这种协议格式能够生成唯一的编码,按照该编码可以唯一的解析出发送数据的内容即可。也正因为各个网络程序之间协议格式的不同,所以才导致了客户端程序都是专用的结构。

13.1.3 网络通讯方式
•在现有的网络中,网络通讯的方式主要有两种:1、 TCP(传输控制协议)方式 2、 UDP(用户数据报协议)方式

•TCP(传输控制协议)方式:类似于拨打电话。进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。

•UDP(用户数据报协议)方式:类似于发送短信。进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

13.2 网络编程技术
•客户端的编程主要由三个步骤实现:

1.建立网络连接:客户端网络编程的第一步都是建立网络连接。在建立网络连接时需要指定连接到的服务器的IP地址和端口号,建立完成以后,会形成一条虚拟的连接,后续的操作就可以通过该连接实现数据交换了。

2.交换数据:连接建立以后,就可以通过这个连接交换数据了。交换数据严格按照请求响应模型进行,由客户端发送一个请求数据到服务器,服务器反馈一个响应数据给客户端,如果客户端不发送请求则服务器端就不响应。根据逻辑需要,可以多次交换数据,但是还是必须遵循请求响应模型。

3.关闭网络连接:在数据交换完成以后,关闭网络连接,释放程序占用的端口、内存等系统资源,结束网络编程。

13.2.1.2 服务器端网络编程步骤

  • 服务器端(Server)是指在网络编程中被动等待连接的程序,服务器端一般实现程序的核心逻辑以及数据存储等核心功能。服务器端的编程步骤和客户端不同,是由四个步骤实现

1.监听端口:服务器端属于被动等待连接,所以服务器端启动以后,不需要发起连接,而只需要监听本地计算机的某个固定端口即可。这个端口就是服务器端开放给客户端的端口,服务器端程序运行的本地计算机的IP地址就是服务器端程序的IP地址。

2.获得连接:当客户端连接到服务器端时,服务器端就可以获得一个连接,这个连接包含客户端的信息,服务器端和客户端也通过该连接进行数据交换。一般在服务器端编程中,当获得连接时,需要开启专门的线程处理该连接,每个连接都由独立的线程实现。

3.交换数据:服务器端通过获得的连接进行数据交换。服务器端的数据交换步骤是首先接收客户端发送过来的数据,然后进行逻辑处理,再把处理以后的结果数据发送给客户端。这个和客户端的数据交换数序不同。服务器端获得的连接和客户端连接是一样的,只是数据交换的步骤不同。当然,服务器端的数据交换也是可以多次进行的。在数据交换完成以后,关闭和客户端的连接。

4.关闭连接:当服务器程序关闭时,需要关闭服务器端,通过关闭服务器端使得服务器监听的端口以及占用的内存可以释放出来,实现了连接的关闭。

总之,无论使用任何语言,任何方式进行基础的网络编程,都必须遵循固定的步骤进行操作,在熟悉了这些步骤以后,可以根据需要进行逻辑上的处理,但是还是必须遵循固定的步骤进行。

13.2.2 Java网络编程技术

基础的网络类——InetAddress类。该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。

关于该类的使用,下面通过一个基础的代码示例演示该类的使用,代码如下:

package inetaddressdemo;

import java.net.*;
/**
 * 演示InetAddress类的基本使用
 */
public class InetAddressDemo {
         public static void main(String[] args) {
                   try{
                            //使用域名创建对象
                            InetAddress inet1 = InetAddress.getByName("www.163.com");
                            System.out.println(inet1);
                            //使用IP创建对象
                            InetAddress inet2 = InetAddress.getByName("127.0.0.1");
                            System.out.println(inet2);
                            //获得本机地址对象
                            InetAddress inet3 = InetAddress.getLocalHost();
                            System.out.println(inet3);
                            //获得对象中存储的域名
                            String host = inet3.getHostName();
                            System.out.println("域名:" + host);
                            //获得对象中存储的IP
                            String ip = inet3.getHostAddress();
                            System.out.println("IP:" + ip);
                   }catch(Exception e){}
         }
}

在该示例代码中,演示了InetAddress类的基本使用,并使用了该类中的几个常用方法,该代码的执行结果是:

13.2.3 TCP编程

  • TCP编程:在Java语言中,对于TCP方式的网络编程提供了良好的支持,在实际实现时,以java.net.Socket类代表客户端连接,以java.net.ServerSocket类代表服务器端连接。在进行网络编程时,底层网络通讯的细节已经实现了比较高的封装,所以在程序员实际编程时,只需要指定IP地址和端口号码就可以建立连接了。正是由于这种高度的封装,一方面简化了Java语言网络编程的难度,另外也使得使用Java语言进行网络编程时无法深入到网络的底层,所以使用Java语言进行网络底层系统编程很困难,但是由于Java语言的网络编程比较简单,所以还是获得了广泛的使用。

•Java语言中客户端的实现步骤:

•建立连接:

Socket socket1 = new Socket(“192.168.1.103”,10000);
Socket socket2 = new Socket(“www.sohu.com”,80);

•数据交换:

OutputStream os = socket1.getOutputStream(); //获得输出流
InputStream is = socket1.getInputStream(); //获得输入流

•关闭网络连接:

socket1.close();

•监听端口:

ServerSocket ss = new ServerSocket(10000);

•获得连接:

Socket socket = ss.accept();

•数据交换:

socket = serverSocket.accept(); //接收客户端发送内容
is = socket.getInputStream();

•关闭网络连接:

ss.close();

下面是一个简单的网络客户端程序示例,该程序的作用是向服务器端发送一个字符串“Hello”,并将服务器端的反馈显示到控制台,数据交换只进行一次,当数据交换进行完成以后关闭网络连接,程序结束。实现的代码如下:

package tcp;
import java.io.*;
import java.net.*;
/**
 * 简单的Socket客户端
 * 功能为:发送字符串“Hello”到服务器端,并打印出服务器端的反馈
 */
public class SimpleSocketClient {
         public static void main(String[] args) {
                   Socket socket = null;
                   InputStream is = null;
                   OutputStream os = null;
                   //服务器端IP地址
                   String serverIP = "127.0.0.1";
                   //服务器端端口号
                   int port = 10000;
                   //发送内容
                   String data = "Hello";
                   try {
                            //建立连接
                            socket = new Socket(serverIP,port);
                            //发送数据
                            os = socket.getOutputStream();
                            os.write(data.getBytes());
                            //接收数据
                            is = socket.getInputStream();
                            byte[] b = new byte[1024];
                            int n = is.read(b);
                            //输出反馈数据
                            System.out.println("服务器反馈:" + new String(b,0,n));
                   } catch (Exception e) {
                            e.printStackTrace(); //打印异常信息
                   }finally{
                            try {
                                     //关闭流和连接
                                     is.close();
                                     os.close();
                                     socket.close();
                            } catch (Exception e2) {}
                   }
         }
}

运行结果:

一个简单的echo服务实现为例子,介绍综合使用示例。echo的意思就是“回声”,echo服务器端实现的功能就是将客户端发送的内容再原封不动的反馈给客户端。

运行结果:

• 在Java API中,实现UDP方式的编程,包含客户端网络编程和服务器端网络编程,主要由两个类实现,分别是:

•DatagramSocket:DatagramSocket类实现“网络连接”,包括客户端网络连接和服务器端网络连接。DatagramSocket实现的就是发送数据时的发射器,以及接收数据时的监听器的角色。类比于TCP中的网络连接,该类既可以用于实现客户端连接,也可以用于实现服务器端连接。

•DatagramPacket:DatagramPacket类实现对于网络中传输的数据封装,该类的对象代表网络中交换的数据。在UDP方式的网络编程中,无论是需要发送的数据还是需要接收的数据,都必须被处理成DatagramPacket类型的对象,该对象中包含发送到的地址、发送到的端口号以及发送的内容等。和TCP方式的网络传输相比,IO编程在UDP方式的网络编程中变得不是必须的内容,结构也要比TCP方式的网络编程简单一些。

•Java语言中客户端的实现步骤:

•建立连接:

DatagramSocket ds = new DatagramSocket();
或者

DatagramSocket ds = new DatagramSocket(5000);

•数据交换:

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);
//构造缓冲数组
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);

•关闭网络连接:

ds.close();

•Java语言中服务端的实现步骤:

  • 监听端口:
DatagramSocket ds = new DatagramSocket(10010);
  • 数据交换:同客户端,发送时需要端口号
//获得客户端的IP
InetAddress clientIP = receiveDp.getAddress();
//获得客户端的端口号
Int clientPort = receiveDp.getPort();
  • 关闭网络连接:
ds.close();

网络协议

  • 网络协议是指对于网络中传输的数据格式的规定。

  • 网络协议设计完成以后,在进行网络编程时,就需要根据设计好的协议格式,在程序中进行对应的编码。客户端程序和服务器端程序需要进行协议处理的代码分别如下:

客户端程序需要完成的处理为:
1、 客户端发送协议格式的生成
2、 服务器端反馈数据格式的解析

服务器端程序需要完成的处理为:
1、 服务器端反馈协议格式的生成
2、 客户端发送协议格式的解析

网络编程示例

13.3.1质数判别示例

  • 程序功能

客户端程序功能:

a) 接收用户控制台输入
b) 判断输入内容是否合法
c) 按照协议格式生成发送数据
d) 发送数据
e) 接收服务器端反馈
f) 解析服务器端反馈信息,并输出

服务器端程序功能:

a) 接收客户端发送数据
b) 按照协议格式解析数据
c) 判断数字是否是质数
d) 根据判断结果,生成协议数据
e) 将数据反馈给客户端

  • 协议格式

客户端发送协议格式:

将用户输入的数字转换为字符串,再将字符串转换为byte数组即可。
客户端发送“quit”字符串代表结束连接。

服务器端发送协议格式:

反馈数据长度为1个字节。数字0代表是质数,1代表不是质数,2代表协议格式错误。

以TCP方式实现结果:

本周代码托管截图


学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 4500行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 1/3 18/38
第三周 400/900 1/4 22/60
第四周 1000/1900 1/5 35/95
第五周 800/2700 1/6 30/125
第六周 700/3400 2/8 30/155
第七周 400/3800 2/10 30/185
第八周 294/4094 2/10 30/185
第九周 356/4450 2/12 30/215
第十周 1061/5511 2/14 25/240

参考资料

推荐阅读