当前位置:文档之家› 第10章 网络编程补充案例

第10章 网络编程补充案例

第10章 网络编程补充案例
第10章 网络编程补充案例

第十章补充案例

案例10-1使用InetAddress类获取与IP信息

一、案例描述

1、考核知识点

编号:4

名称:InetAddress类

2、练习目标

?掌握InetAddress类的相关API

?掌握如何使用InetAddress类中的方法获取计算机的主机名和IP地址等信息。

3、需求分析

InetAddress类中提供了一系列与IP地址相关的方法,利用这些方法可以获取到指定计算机的主机名、IP地址以及连接状态等信息。为了让初学者掌握InetAddress类中常用方法的使用,本案例将针对如何通过InetAddress类中的方法获取计算机的IP地址、主机名等功能进行演示。

4、设计思路(实现原理)

1)编写Example01类。

2)在main()方法中,通过InetAddress类的静态方法getLocalHost()创建实例对象,并通过该对

象完成获取计算机主机名和计算机IP地址的操作。

3)分别将获取到的主机名和IP地址输出。

二、案例实现

import https://www.doczj.com/doc/2011045892.html,.InetAddress;

import https://www.doczj.com/doc/2011045892.html,.UnknownHostException;

public class Example01 {

public static void main(String[] args) throws UnknownHostException {

//获取本机的IP地址

InetAddress address = InetAddress.getLocalHost();

//以字符串形式返回IP地址

String ip = address.getHostAddress();

//获取此IP地址的主机名

String name = address.getHostName();

System.out.println("本机的ip地址是:"+ip);

System.out.println("本机的hostName是:"+name);

}

}

运行结果如图10-1所示。

图10-1运行结果

三、案例总结

1、InetAddress类用于封装一个IP地址,并提供了一系列与IP地址相关的方法,其中,getByName(String host)方法表示获取指定主机的IP地址,常用于获取远程计算机的IP信息,isReachable(int timeout)方法表示判断指定的时间内IP地址是否可以到达,常用于测试网络是否通畅。

2、InetAddress类的getHostName()方法是用来获取IP地址的主机名,而为什么有的时候获取到的不是主机名而是域名?

案例10-2UDP网络程序

一、案例描述

1、考核知识点

编号:

名称:DatagramPacket类和DatagramSocket类

2、练习目标

?掌握DatagramPacket类和DatagramSocket类的作用

?掌握如何使用DatagramPacket类和DatagramSocket类通过编写简单的UDP程序。

3、需求分析

DatagramPacket用于封装UDP通信中发送或者接收的数据,DatagramSocket类用于发送和接收DatagramPacket数据包。为了让初学者掌握这两个类的作用,本案例将通过DatagramPacket 类和DatagramSocket类实现简单的数据通信,并通过观察两个命令行窗口中数据输出的先后顺序,从而掌握UDP网络程序中接收端和发送端的执行原理。

4、设计思路(实现原理)

1)编写数据接收类ReceiveDemo,在ReceiveDemo类中创建接收端的Socket服务对象,并依次

编写创建数据包、调用接收方法、解析数据包并向命令行输出内容,释放资源等操作。

2)编写数据发送类SendDemo,在SendDemo类中创建发送端的Socket服务对象,并依次编写

创建数据包,打包数据、发送数据、释放资源等操作。

3)依次执行ReceiveDemo和SendDemo类,观察命令行输出变化。

二、案例实现

UDP网络程序中接受数据端,代码如下:

import java.io.IOException;

import https://www.doczj.com/doc/2011045892.html,.DatagramPacket;

import https://www.doczj.com/doc/2011045892.html,.DatagramSocket;

import https://www.doczj.com/doc/2011045892.html,.InetAddress;

public class ReceiveDemo {

public static void main(String[] args) throws IOException {

// 创建接收端Socket服务对象

DatagramSocket ds = new DatagramSocket(12306);

// 创建数据包(接收容器)

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

System.out.println("接受数据服务已打开,等待接受数据");

// 调用接收方法

ds.receive(dp);

// 解析数据包,把数据显示在控制台

InetAddress address = dp.getAddress();

String ip = address.getHostAddress();

byte[] bys2 = dp.getData();

int length = dp.getLength();

String s = new String(bys2, 0, length);

System.out.println(ip + "***" + s);

System.out.println("接受数据完毕,接受数据服务关闭");

// 释放资源

ds.close();

}

}

UDP网络程序中发送数据端,代码如下:

import java.io.IOException;

import https://www.doczj.com/doc/2011045892.html,.DatagramPacket;

import https://www.doczj.com/doc/2011045892.html,.DatagramSocket;

import https://www.doczj.com/doc/2011045892.html,.InetAddress;

public class SendDemo {

public static void main(String[] args) throws IOException {

// 创建发送端Socket服务对象

DatagramSocket ds = new DatagramSocket();

// 创建数据,并把数据打包

String str = "hello,udp,我来了";

byte[] bys = str.getBytes();

int length = bys.length;

InetAddress address = InetAddress.getByName("127.0.0.1");

int port = 12306;

DatagramPacket dp = new DatagramPacket(bys, length, address, port);

System.out.println("发送数据服务已打开");

System.out.println("发送数据是:"+str);

// 发送数据

ds.send(dp);

System.out.println("发送完毕,关闭服务");

// 释放资源

ds.close();

}

}

运行接受端程序,运行结果如图10-2所示。

图10-2运行结果

运行发送端程序,运行结果如图10-3所示。

图10-3运行结果

观察接受端控制台的输出,运行结果如图10-4所示。

图10-4运行结果

从图10-2中可以看出,当运行ReceiveDemo类时,程序会在receive()方法处停顿,并一直处于停滞状态。当运行SendDemo类时,ReceiveDemo类中的receive()方法接受到了数据,并向下执行直到程序结束。

三、案例总结

1、在创建发送端的DatagramSocket对象时,可以不指定端口号,而案例中指定端口号目的就是,为

了每次运行时接收端的getPort()方法返回值都是一致的,否则发送端的端口号由系统自动分配,接收端的getPort()方法的返回值每次都不同。

2、运行例程ReceiveDemo,有时会出现如图10-5所示的异常。

图10-5运行结果

出现图中所示的情况,是因为在一台计算机中,一个端口号上只能运行一个程序,而我们编写的UDP 程序所使用的端口号已经被其它的程序占用。遇到这种情况,可以在命令行窗口输入"netstat -anb"命令来查看当前计算机端口占用情况,具体如图10-6所示。

图10-6端口占用情况

案例10-3多线程的UDP网络程序

一、案例描述

1、考核知识点

编号:00110007

名称:UDP案例

2、练习目标

?通过编写多线程的UDP网络程序,掌握如何在单个窗口中实现接收与发送数据。

3、需求分析

在上一个案例中,通过两个命令行窗口输出数据让我们初步了解了单线程的UDP网络程序,

为了让初学者更加直观和深入的掌握网络编程,本案例将整合多线程技术,在同一个命令行窗口中同时实现接收和发送数据的功能。

4、设计思路(实现原理)

1)编写数据接收类ReceiveThread,该类实现了Runnable接口,重写run()方法实现不断接受客

户端发送数据的功能。

2)编写数据发送类SendThread,该类同样实现了SendThread接口,重写run()方法实现通过键

盘录入数据,将数据向接收端发送的功能。

3)编写测试类Example02,在main()方法中,同时启动接收端和发送端程序。

二、案例实现

UDP网络程序中接受数据端,代码如下:

import java.io.IOException;

import https://www.doczj.com/doc/2011045892.html,.DatagramPacket;

import https://www.doczj.com/doc/2011045892.html,.DatagramSocket;

public class ReceiveThread implements Runnable {

public void run() {

try {

// 创建接收端Socket对象

DatagramSocket ds = new DatagramSocket(10086);

// 创建数据包

while (true) {

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

//接收数据

ds.receive(dp);

// 解析数据

String ip = dp.getAddress().getHostAddress();

String s = new String(dp.getData(), 0, dp.getLength());

System.out.println("接收端:从" + ip + " 主机接收到的数据是: " + s);

if ("bye".equals(s)) {

System.out.println("******聊天室关闭******");

ds.close();

break;

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

UDP网络程序中发送数据端,代码如下:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import https://www.doczj.com/doc/2011045892.html,.DatagramPacket;

import https://www.doczj.com/doc/2011045892.html,.DatagramSocket;

import https://www.doczj.com/doc/2011045892.html,.InetAddress;

public class SendThread implements Runnable {

public void run() {

try {

// 创建发送端Socket对象

DatagramSocket ds = new DatagramSocket();

// 封装键盘录入

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

// 创建数据,并打包

String line = null;

while ((line = br.readLine()) != null) {

byte[] bys = line.getBytes();

DatagramPacket dp = new DatagramPacket(bys, bys.length,

InetAddress.getByName("172.16.26.21"), 10086);

ds.send(dp);

if ("bye".equals(line)) {

// 释放资源

br.close();

ds.close();

break;

}

}

// 释放资源

br.close();

ds.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

编写测试类Example02,代码如下:

public class Example02 {

public static void main(String[] args) {

SendThread st = new SendThread();

ReceiveThread rt = new ReceiveThread();

Thread t1 = new Thread(st);

Thread t2 = new Thread(rt);

t1.start();

t2.start();

}

}

运行Example02,依次键入“hello itcast”和“bye”后,结果如图10-7所示。

图10-7运行结果

从图10-7中可以看出,Example02类实现了在一个命令行窗口中同时发送和接收数据的功能。并且当发送端发送“bye”时,程序结束。

三、案例总结

1、在网络程序中,为了保证程序的稳定性,服务器一般不会轻易关闭,所以在编写服务端时,通常不会编写关闭服务端的代码。

2、UDP之所以是一种不可靠的网络协议,是因为UDP排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。

思考:既然UDP一直被业内称为不可靠的网络协议。但是,自1980年发布以来,UDP协议仍然继续在主流应用中发挥着作用。那么,请想一想身边有哪些应用程序使用的是UDP协议。

案例10-4TCP网络程序

一、案例描述

1、考核知识点

编号:00110008/00110009

名称:ServerSocket类/Socket类

2、练习目标

?通过编写简单的TCP程序,掌握ServerSocket、Socket类的具体用法。

3、需求分析

ServerSocket用于负责监听某台计算机的某个端口号接收来自客户端的请求,是网络程序中的服务器端,Socket用于根据指定的IP地址和端口号向ServerSocket端交互,是网络程序中的客户端。为了让初学者掌握这两个类的作用,本案例将通过ServerSocket类和Socket类实现简单的数据通信,并通过观察两个命令行窗口中数据输出的先后顺序,从而增加对TCP网络程序中客户端和服务端的执行原理。

4、设计思路(实现原理)

1)编写服务器端类ServerDemo,在ServerDemo类中创建服务器端ServerSocket对象,并依次

编写监听连接、获取输入流,打印读取数据,释放资源等操作。

2)编写客户端类ClientDemo,在ClientDemo类中创建客户端Socket对象,并分别编写建立连

接、获取输出流,释放资源等步骤。

3)依次执行ServerDemo和ClientDemo类,观察命令行输出变化。

二、案例实现

TCP网络程序中服务端,代码如下:

import java.io.IOException;

import java.io.InputStream;

import https://www.doczj.com/doc/2011045892.html,.ServerSocket;

import https://www.doczj.com/doc/2011045892.html,.Socket;

public class ServerDemo {

public static void main(String[] args) throws IOException {

// 创建服务器端Socket对象

ServerSocket ss = new ServerSocket(10010);

System.out.println("服务端已开启,等待客户端发送数据。");

// 监听连接

Socket s = ss.accept();//阻塞

// 获取输入流,读取数据,并显示

InputStream is = s.getInputStream();

byte[] bys = new byte[1024];

int len = is.read(bys);//阻塞

String client = new String(bys, 0, len);

System.out.println(client);

// 释放资源

System.out.println("已接收客户端发送的数据,服务端关闭。");

s.close();

}

}

TCP网络程序中客户端,代码如下:

import java.io.IOException;

import java.io.OutputStream;

import https://www.doczj.com/doc/2011045892.html,.Socket;

public class ClientDemo {

public static void main(String[] args) throws IOException {

// 创建客户端的Socket对象,建立连接

Socket s = new Socket("172.16.26.21", 10010);

System.out.println("客户端已打开,等待发送数据。");

// 获取输出流,写数据即可

OutputStream os = s.getOutputStream();

os.write("hello,tcp,我来了".getBytes());

// 释放资源

System.out.println("发送完毕,关闭客户端服务。");

s.close();

}

}

首先开启服务端程序,运行结果如图10-8所示。

图10-8运行结果

然后开启客户端程序,运行结果如图10-9所示。

图10-9运行结果

此时,再观察服务端控制台的输出,运行结果如图10-10所示。

图10-10运行结果

三、案例总结

1、在使用TCP协议编写网络程序时,服务端和客户端的端口号必须保持一致,否则会出现下列错误。

相关主题
文本预览
相关文档 最新文档