Java网络编程详解(No.18)
1、网络编程的目的(Purpose Of Network Programming)
网络编程的目的主要就是“实现不同网络设备之间的资源共享与信息传递”。
2、网络编程的要素(Elements Of network Programming)
2.1、网络通信地址(Network Communication Address)
即,“IP地址与端口号(如:192.168.1.1:8080)”,可准确定位到网络上一台或多台主机。
2.2、网络通信协议(Network Communication Protocol)
即,“TCP或者UDP”,可在定位到指定网络主机后决定如何通信。
3、IP地址(Internet Protocol Address)
3.1、本地主机(Local Host)
本地主机(即,本机,localhost)IP地址:“127.0.0.1”。
3.2、分类(Classification)
-
3.2.1、IPV4(Internet Protocol Version 4)
4个字节(即,4个无符号的十进制整数,每个整数取值范围0~255),总长度32位(即,32bit),总数量为”2^32“,如:”103.235.46.39“。
- 3.2.1.1、公网(Public Network,亦即”互联网“)
- 3.2.1.2、私网(Private Network,亦即”局域网“)
- 专给组织内部使用的IP地址(如:”192.168.0.123“)。
-
3.2.2、IPV6(Internet Protocol Version 6)
16个字节(即,8个无符号的十六进制整数,每个整数取值范围0000~FFFF),总长度128位(即,128bit),总数量为”2^128“,如:”1111:3333:5555:7777:9999:BBBB:DDDD:FFFF“。
3.3、域名(Domain Name)
即,“网域名称”,IP地址与域名是一对多的关系。一个IP地址可以对应多个域名,但是一个域名只有一个IP地址。如:”www.baidu.com“。
3.4、InetAddress类(InetAddress Class)
3.4.1、示例代码(Sample Code)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* InetAddress类:即,“Internet协议(IP)地址类”。
*/
public class InetAddressClass {
public static void main(String[] args) {
try {
//查询本机IP地址
InetAddress inetAddress0=InetAddress.getByName("");
System.out.println("inetAddress0 = " + inetAddress0);
InetAddress inetAddress1=InetAddress.getByName("127.0.0.1");
System.out.println("inetAddress1 = " + inetAddress1);
InetAddress inetAddress2=InetAddress.getByName("localhost");
System.out.println("inetAddress2 = " + inetAddress2);
InetAddress inetAddress3=InetAddress.getLocalHost();
System.out.println("inetAddress3 = " + inetAddress3);
//查询网站IP地址
InetAddress inetAddress4=InetAddress.getByName("www.baidu.com");
System.out.println("inetAddress4 = " + inetAddress4);
/**
* InetAddress类常用方法
*/
//查看主机IP地址对应的字节数组
System.out.println("inetAddress4.getAddress() = " + inetAddress4.getAddress());
//查看规范的主机名称
System.out.println("inetAddress4.getCanonicalHostName() = " + inetAddress4.getCanonicalHostName());
//查看主机IP地址
System.out.println("inetAddress4.getHostAddress() = " + inetAddress4.getHostAddress());
//查看主机名称(即,域名或者主机电脑名称)
System.out.println("inetAddress4.getHostName() = " + inetAddress4.getHostName());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
3.4.2、运行结果(Run Result)。
其运行结果,如下所示。
inetAddress0 = localhost/127.0.0.1
inetAddress1 = /127.0.0.1
inetAddress2 = localhost/127.0.0.1
inetAddress3 = PC2004/10.30.90.78
inetAddress4 = www.baidu.com/14.215.177.39
inetAddress4.getAddress() = [B@4f3f5b24
inetAddress4.getCanonicalHostName() = 14.215.177.39
inetAddress4.getHostAddress() = 14.215.177.39
inetAddress4.getHostName() = www.baidu.com
4、端口号(Port Number)
端口号代表计算机上一个程序的进程,且不同程序的进程端口号不同。
4.1、端口号范围(Port Number Range)
端口号取值范围“0~65535”,且同一协议下,端口号不能冲突(即不能相同),而不同协议下,端口号可以相同(如“TCP端口为123,UDP端口也可以为123 ”)。
4.2、端口号分类(Port Number Classification)
-
4.2.1、公认端口(0~1023)
一般代表固定服务的协议,不允许随意作为它用,如下所示。
- 4.2.1.1、HTTP(80)。
- 4.2.1.2、HTTPS(443)。
- 4.2.1.3、FTP(21)。
- 4.2.1.4、Telnet(23)。
- 4.2.1.5、等等。
-
4.2.2、注册端口(1024~49151)
一般分配用户或者程序的服务。
- 4.2.2.1、Tomcat(8080)。
- 4.2.2.2、MySQL(3306)。
- 4.2.2.3、Oracle(1521)。
- 4.2.2.4、等等。
-
4.2.3、动态(私有)端口(49152~65535)
一般从1024开始动态分配端口号。
4.3、查看端口相关信息的DOS命令(DOS Command Of View Port Related Information)
netstat -ano #查看所有的端口信息
netstat -ano|findstr "5396" #查看指定的端口信息
tasklist|findstr "5056" #查看指定端口的进程信息
4.4、InetSocketAddress类(InetSocketAddress Class)
4.4.1、示例代码(Sample Code)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
/**
* InetSocketAddress类:即,实现IP套接字地址(IP地址+端口号),它也可以是一对(主机名+端口号),在这种情况下将尝试解析主机名。
*/
public class InetSocketAddressClass {
public static void main(String[] args) throws UnknownHostException {
InetSocketAddress inetSocketAddress1=new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress inetSocketAddress2=new InetSocketAddress("localhost",8080);
InetSocketAddress inetSocketAddress3=new InetSocketAddress(InetAddress.getByName("127.0.0.1"),8080);
InetSocketAddress inetSocketAddress4=new InetSocketAddress(InetAddress.getByName("localhost"),8080);
System.out.println("inetSocketAddress1 = " + inetSocketAddress1);
System.out.println("inetSocketAddress2 = " + inetSocketAddress2);
System.out.println("inetSocketAddress3 = " + inetSocketAddress3);
System.out.println("inetSocketAddress4 = " + inetSocketAddress4);
System.out.println("inetSocketAddress1.getAddress() = " + inetSocketAddress1.getAddress());//IP地址
System.out.println("inetSocketAddress1.getHostName() = " + inetSocketAddress1.getHostName());//主机名称
System.out.println("inetSocketAddress1.getPort() = " + inetSocketAddress1.getPort());//端口号
}
}
4.4.2、运行结果(Run Result)。
其运行结果,如下所示。
inetSocketAddress1 = /127.0.0.1:8080
inetSocketAddress2 = localhost/127.0.0.1:8080
inetSocketAddress3 = /127.0.0.1:8080
inetSocketAddress4 = localhost/127.0.0.1:8080
inetSocketAddress1.getAddress() = /127.0.0.1
inetSocketAddress1.getHostName() = 127.0.0.1
inetSocketAddress1.getPort() = 8080
5、通讯协议(Communication Protocol)
5.1、OSI七层模型与TCP/IP四层模型对应关系(Relation Between OSI Seven Layer Model And TCP/IP Four Layer Model)
OSI七层模型与TCP/IP四层模型对应关系,如下表所示。
OSI七层模型 | TCP/IP四层模型 | 相关协议 |
---|---|---|
应用层(Application Layer) | 应用层(Application Layer) | HTTP(Hyper Text Transfer Protocol,超文本传输协议)、HTTPS(Hyper Text Transfer Protocol Over SecureSocket Layer,在安全套接字层之上的超文本传输协议,即“超文本传输安全协议”)、DHCP(Dynamic Host COnfiguration Protocol,动态主机配置协议)、FTP(File Transfer Protocol,文件传输协议)、TFTP(Trivial File Transfer Protocol,简单(普通)文件传输协议)、SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)、POP3(Post Office Protocol-Version 3,邮局协议版本3)、IMAP4(Internet Message Access Protocol 4,第四版因特网信息存取协议)、SSL(Secure Sockets Layer,安全套接字层,即“安全套接字协议”)、TLS(Transport Layer Security,传输层安全,即“传输安全协议”) |
表示层(Presentation Layer) | Telnet(远程终端协议)、SNMP(Simple Network Management Protocol,简单网络管理协议) | |
会话层(Session Layer) | DNS(Domain Name System,网域名称系统,即“域名系统”) | |
传输层(Transport Layer) | 传输层(Transport Layer) | TCP(Transmission Control Protocol,传输控制协议)、UDP(User Datagram Protocol,用户数据报协议) |
网络层(Network Layer) | 网络层(Network Layer) | IP(Internet Protocol,网际互联协议,即“互联网协议”)、ICMP(Internet Control Message Protocol,互联网控制报文协议)、ARP(Address Resolution Protocol,地址解析协议)、RARP(Reverse Address Resolution Protocol,反向地址解析协议,即“反向地址转换协议”) |
数据链路层(Data Link Layer) | 数据链路层(Data Link Layer) | FDDI(Fiber Distributed Data Interface,光纤分布式数据接口)、Ethernet(以太网)、PDN(Public Data Network,公用数据网)、SLIP(Serial Line Internet Protocol,串行线路互联网协议) |
物理层(Physical Layer) | EIA/TIA RS-232、RJ-45、IEEE 802.1A、IEEE 802.2、IEEE 802.11 |
5.2、TCP(Transmission Control Protocol,传输控制协议)
使用TCP协议通信(如“打电话”),其特点如下所示。
-
5.2.1、需要连接,且连接稳定。
-
其连接需要三次握手,其关闭需要四次挥手。
三次握手,如下所示。 小津:小民,你好! 小民:小津,你好! 小津:小民,很高兴遇见你! 四次挥手,如下所示。 小津:小民,再见! 小民:小津,再见! 小民:小津,后会有期! 小津:小民,后会有期!
-
-
5.2.2、需要明确的客户端与服务端。
-
5.2.3、只有传输完成后才会释放连接,效率低。
5.3、UDP(User Datagram Protocol,用户数据报协议)
使用UDP协议通信(如“发短信”),其特点如下所示。
- 5.3.1、不需要连接,且连接不稳定。
- 5.3.2、客户端与服务端没有明确的界限,一般称为“发送端和接收端”。
6、基于TCP通信协议的文字聊天的实现(Implementation Of Text Chat Based On TCP Communication Protocol)
6.1、示例代码(Sample Code)。
其示例代码,如下所示。
6.1.1、客户端(Client)。
package com.xueshanxuehai.networkprogramming.tcp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* 文字聊天:客户端,TCP通信协议
*/
public class TextChatClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
//服务器IP地址
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
//服务器端口号
int serverPort = 12345;
//创建客户端Socket(套接字),连接服务器
socket = new Socket(serverIP, serverPort);
//创建输出流,发送消息
outputStream = socket.getOutputStream();
String myTCPClientStr = "Hello!TCP!";
outputStream.write(myTCPClientStr.getBytes());
System.out.println("TCP文字聊天客户端已发送信息:" + myTCPClientStr);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭输出流
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭客户端Socket(套接字)
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.1.2、服务器(Server)。
package com.xueshanxuehai.networkprogramming.tcp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 文字聊天:服务器,TCP通信协议
*/
public class TextChatServer {
public static void main(String[] args) {
ServerSocket serverSocket=null;
Socket socket=null;
InputStream inputStream=null;
ByteArrayOutputStream byteArrayOutputStream=null;
try {
//创建服务器ServerSocket(服务器套接字)
serverSocket=new ServerSocket(12345);
//创建客户端Socket(套接字),接收客户端信息
socket=serverSocket.accept();
//创建输入流,获取客户端信息
inputStream = socket.getInputStream();
//创建管道流(处理流),存储客户端信息
byteArrayOutputStream=new ByteArrayOutputStream();
byte[] bytes=new byte[1<<6];
int len;
while((len=(inputStream.read(bytes)))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println("TCP文字聊天服务器已接收信息:"+byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭管道流(处理流)
if(byteArrayOutputStream!=null){
try {
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭输入流
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭客户端Socket(套接字)
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭服务器ServerSocket(服务器套接字)
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.2、运行结果(Run Result)。
其运行结果,如下所示。
6.2.1、客户端(Client)。
TCP文字聊天客户端已发送信息:Hello!TCP!
6.2.2、服务器(Server)。
TCP文字聊天服务器已接收信息:Hello!TCP!
7、基于TCP通信协议的文件上传的实现(Implementation Of File Upload Based On TCP Communication Protocol)
7.1、示例代码(Sample Code)**。
其示例代码,如下所示。
7.1.1、客户端(Client)。
package com.xueshanxuehai.networkprogramming.tcp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 文字上传:客户端,TCP通信协议
*/
public class FileUploadClient {
public static void main(String[] args) throws Exception {
//创建客户端Socket(套接字),连接服务器
Socket socket=new Socket(InetAddress.getByName("localhost"),12321);
//创建输出流,上传文件
OutputStream outputStream=socket.getOutputStream();
//上传文件路径及名称
String filePathName="E:\\Environment\\Java\\IDEA\\StageOne\\javase\\resources\\1.png";
//读取文件
FileInputStream fileInputStream=new FileInputStream(new File(filePathName));
//写出文件
byte[] buffer1=new byte[1<<6];
int len1;
while((len1=(fileInputStream.read(buffer1)))!=-1){
outputStream.write(buffer1,0,len1);
}
System.out.println("TCP客户端已上传文件:" + filePathName);
//通知服务器客户端已发送完成
socket.shutdownOutput();//关闭输出流
//等待服务器接收完成,然后再断开连接
InputStream inputStream=socket.getInputStream();
//创建管道流(处理流),存储服务器信息
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
byte[] buffer2=new byte[1<<6];
int len2;
while((len2=(inputStream.read(buffer2)))!=-1){
byteArrayOutputStream.write(buffer2,0,len2);
}
System.out.println("TCP客户端已接收服务器反馈信息:" + byteArrayOutputStream.toString());
//关闭资源
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
inputStream.close();
fileInputStream.close();
outputStream.flush();
outputStream.close();
socket.close();
}
}
7.1.2、服务器(Server)。
package com.xueshanxuehai.networkprogramming.tcp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 文件上传:服务器,TCP通信协议
*/
public class FileUploadServer {
public static void main(String[] args) throws Exception {
//创建服务器ServerSocket(服务器套接字)
ServerSocket serverSocket=new ServerSocket(12321);
//创建客户端Socket(套接字),接收客户端信息,监听客户端的连接
Socket socket=serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//创建输入流,获取客户端信息
InputStream inputStream=socket.getInputStream();
//上传文件路径及名称
String filePathName="E:\\Environment\\Java\\IDEA\\StageOne\\javase\\resources\\1_output.png";
//写出文件
FileOutputStream fileOutputStream=new FileOutputStream(new File(filePathName));
byte[] buffer=new byte[1<<6];
int len;
while((len=(inputStream.read(buffer)))!=-1){
fileOutputStream.write(buffer,0,len);
}
System.out.println("TCP服务器已上传文件:" + filePathName);
//通知客户端服务器已接收完成,客户端可以断开连接
OutputStream outputStream=socket.getOutputStream();
String outputStreamStr="服务器已接收完成";
outputStream.write(outputStreamStr.getBytes());
System.out.println("TCP服务器已反馈客户端信息:"+outputStreamStr);
//关闭资源
outputStream.flush();
outputStream.close();
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
7.2、运行结果(Run Result)。
其运行结果,如下所示。
7.2.1、客户端(Client)。
TCP客户端已上传文件:E:\Environment\Java\IDEA\StageOne\javase\resources\1.png
TCP客户端已接收服务器反馈信息:服务器已接收完成
7.2.2、服务器(Server)。
TCP服务器已上传文件:E:\Environment\Java\IDEA\StageOne\javase\resources\1_output.png
TCP服务器已反馈客户端信息:服务器已接收完成
8、基于UDP通信协议的消息发送与接收的实现(Implementation Of Message Send And Receive Based On UDP Communication Protocol)
8.1、示例代码(Sample Code)。
8.1.1、发送端(Sender)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
/**
* 消息发送端
*/
public class MessageSender {
public static void main(String[] args) throws Exception {
//创建DatagramSocket
DatagramSocket datagramSocket=new DatagramSocket();
//创建IP
InetAddress inetAddress=InetAddress.getByName("localhost");
//创建端口号
int port=12345;
//创建数据报包
String str="消息发送端";
//创建DatagramPacket
DatagramPacket datagramPacket=new DatagramPacket(str.getBytes(),0,str.getBytes().length,new InetSocketAddress(inetAddress,port));
//发送数据包
datagramSocket.send(datagramPacket);
//输出消息
System.out.println("已发送消息");
//关闭资源
datagramSocket.close();
}
}
8.1.2、接收端(Receiver)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* 消息接收端
*/
public class MessageReceiver {
public static void main(String[] args) throws Exception {
//创建DatagramSocket,开放端口
DatagramSocket datagramSocket=new DatagramSocket(12345);
//接收数据包
byte[] buffer = new byte[1 << 6];
DatagramPacket datagramPacket=new DatagramPacket(buffer,0,buffer.length);
datagramSocket.receive(datagramPacket);//阻塞接收
//输出消息
System.out.println("已接收消息");
System.out.println(datagramPacket.getAddress());
System.out.println(new String(datagramPacket.getData(), 0, datagramPacket.getLength()));
//关闭资源
datagramSocket.close();
}
}
8.2、运行结果(Run Result)。
8.2.1、发送端(Sender)。
其运行结果,如下所示。
已发送消息
8.2.2、接收端(Receiver)。
其运行结果,如下所示。
已接收消息
/127.0.0.1
消息发送端
9、基于UDP通信协议的文字聊天的实现(Implementation Of Text Chat Based On UDP Communication Protocol)
9.1、示例代码(Sample Code)。
9.1.1、发送端(Sender)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* 文字聊天发送端
*/
public class TextChatSender {
public static void main(String[] args) throws Exception {
//创建DatagramSocket
DatagramSocket datagramSocket=new DatagramSocket();
//创建数据报包,即,发送的聊天信息
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
//循环等待发送的聊天信息,直到发送指定结束信息为止
for (;;){
//发送数据包
String str=bufferedReader.readLine();
byte[] buffer=str.getBytes();
DatagramPacket datagramPacket=new DatagramPacket(buffer,0,buffer.length,new InetSocketAddress("localhost",12345));
datagramSocket.send(datagramPacket);//发送信息
System.out.println("已发送消息:"+str);//输出信息
if(str.equals("end")){
break;//退出循环
}
}
//关闭资源
bufferedReader.close();
datagramSocket.close();
}
}
9.1.2、接收端(Receiver)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* 文字聊天接收端
*/
public class TextChatReceiver {
public static void main(String[] args) throws Exception {
//创建DatagramSocket,开放端口
DatagramSocket datagramSocket = new DatagramSocket(12345);
//循环等待接收的聊天信息,直到接收指定结束信息为止
for (; ; ) {
//接收数据包
byte[] buffer = new byte[1 << 6];
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
datagramSocket.receive(datagramPacket);//接收信息
//输出信息
String str = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println("已接收消息:" +str);
if(str.equals("end")){
break;//退出循环
}
}
//关闭资源
datagramSocket.close();
}
}
9.2、运行结果(Run Result)。
9.2.1、发送端(Sender)。
其运行结果,如下所示。
123
已发送消息:123
学习Java
已发送消息:学习Java
end
已发送消息:end
9.2.2、接收端(Receiver)。
其运行结果,如下所示。
已接收消息:123
已接收消息:学习Java
已接收消息:end
10、基于UDP通信协议的多线程在线咨询的实现(Implementation Of Multi-Thread Online Consultation Based On UDP Communication Protocol)
10.1、示例代码(Sample Code)。
- 10.1.1、OnLineConsultationSender类。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
* 在线咨询发送端
*/
public class OnLineConsultationSender implements Runnable{
DatagramSocket datagramSocket=null;
BufferedReader bufferedReader=null;
private int fromPort;
private String toIP;
private int toPort;
public OnLineConsultationSender(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
//创建DatagramSocket
datagramSocket=new DatagramSocket(this.fromPort);
//创建数据报包,即,发送的聊天信息
bufferedReader=new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
//循环等待发送的聊天信息,直到发送指定结束信息为止
for (;;){
try {
//发送数据包
String str= bufferedReader.readLine();
byte[] buffer=str.getBytes();
DatagramPacket datagramPacket=new DatagramPacket(buffer,0,buffer.length,new InetSocketAddress(this.toIP,this.toPort));
datagramSocket.send(datagramPacket);//发送信息
if(str.equals("再见")){
break;//退出循环
}
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭资源
try {
bufferedReader.close();
datagramSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 10.1.2、OnlineConsultationReceiver类。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 在线咨询接收端
*/
public class OnlineConsultationReceiver implements Runnable{
DatagramSocket datagramSocket=null;
private int fromPort;
private String fromMsg;
public OnlineConsultationReceiver(int fromPort, String fromMsg) {
this.fromPort = fromPort;
this.fromMsg = fromMsg;
//创建DatagramSocket,开放端口
try {
datagramSocket = new DatagramSocket(this.fromPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
//循环等待接收的聊天信息,直到接收指定结束信息为止
for (; ; ) {
try {
//接收数据包
byte[] buffer = new byte[1 << 6];
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
datagramSocket.receive(datagramPacket);//接收信息
//输出信息
String str = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println(this.fromMsg+":" +str);
if(str.equals("再见")){
break;//退出循环
}
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭资源
datagramSocket.close();
}
}
- 10.1.3、Student类。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
/**
* 学生类
*/
public class Student {
public static void main(String[] args) {
new Thread(new OnLineConsultationSender(1111,"localhost",1221)).start();
new Thread(new OnlineConsultationReceiver(2112,"教师")).start();
}
}
- 10.1.4、Teacher类。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.udp;
/**
* 教师类
*/
public class Teacher {
public static void main(String[] args) {
new Thread(new OnLineConsultationSender(2222,"localhost",2112)).start();
new Thread(new OnlineConsultationReceiver(1221,"学生")).start();
}
}
10.2、运行结果(Run Result)。
10.2.1、Student类。
其运行结果,如下所示。
老师!请问如何学好Java?
教师:打好基础,坚持不懈!
好的,谢谢!
教师:不用谢!
再见
教师:再见
10.2.2、Teacher类。
其运行结果,如下所示。
学生:老师!请问如何学好Java?
打好基础,坚持不懈!
学生:好的,谢谢!
不用谢!
学生:再见
再见
11、基于URL的网络资源下载的实现(Implementation Of Download Network Resources Based On URL)
URL(Uniform Resource Locator,统一资源定位符)就是指“网络地址”,亦即,互联网上用于指定信息位置的表示方法。
11.1、示例代码(Sample Code)。
其示例代码,如下所示。
package com.xueshanxuehai.networkprogramming.url;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
/**
* 使用URL类与HttpURLConnection类:实现网络资源的下载
*/
public class DownloadNetworkResources {
public static void main(String[] args) throws Exception {
//下载资源地址
//URL url=new URL("http://localhost:8080/xueshanxuehai/URLTest.txt");//本地网络文本文件,且前提是下载并打开与配置好Tomcat软件相关文件
//URL url=new URL("https://m801.music.126.net/20210814200026/79c607cbebbb813e42e19add60c91290/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/10238787644/5b2c/ceb8/9375/1ada3bed6f6dfc84435f498d67efb9de.m4a");//在线网络音频文件
URL url=new URL("https://p1.music.126.net/KS0TddHKX8c3atG3CkmdUw==/109951166264542938.jpg?param=200y200");//在线网络图片文件
//输出下载资源信息
System.out.println("url.getProtocol() = " + url.getProtocol());//协议
System.out.println("url.getHost() = " + url.getHost());//主机
System.out.println("url.getPort() = " + url.getPort());//端口号
System.out.println("url.getPath() = " + url.getPath());//文件路径
System.out.println("url.getFile() = " + url.getFile());//文件完整路径
System.out.println("url.getQuery() = " + url.getQuery());//查询参数
//连接到下载资源
// HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//本地网络文件
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(new Proxy(Proxy.Type.HTTP,new InetSocketAddress("10.30.90.55",908)));//在线网络文件
//读取下载资源
InputStream inputStream=httpURLConnection.getInputStream();
//写出下载资源
//FileOutputStream fileOutputStream=new FileOutputStream("URLTest.txt");//本地网络文本文件
//FileOutputStream fileOutputStream=new FileOutputStream("URLTest.m4a");//在线网络音频文件
FileOutputStream fileOutputStream=new FileOutputStream("URLTest.jpg");//在线网络图片文件
byte[] buffer=new byte[1<<6];
int len;
while((len=(inputStream.read(buffer)))!=-1){
fileOutputStream.write(buffer,0,len);
}
//关闭资源
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
httpURLConnection.disconnect();//断开连接
}
}
11.2、运行结果(Run Result)。
其运行结果,如下所示。
url.getProtocol() = https
url.getHost() = p1.music.126.net
url.getPort() = -1
url.getPath() = /KS0TddHKX8c3atG3CkmdUw==/109951166264542938.jpg
url.getFile() = /KS0TddHKX8c3atG3CkmdUw==/109951166264542938.jpg?param=200y200
url.getQuery() = param=200y200