网络编程
一、Java基本的网络支持
java提供了java.net这个包。


1、使用InetAddress

2、使用URLDecoder和URLEncoder
上面这个%E7%94%98%E5%87%8C%E6%98%8A是一种application/x-www-form-urlencoded MIME格式的字符串。
3、URL、URLConnection、URLPermission
网络地址的基本组成:
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
下载文件的工具类:
package network.download;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @author:Gan Linghao
* @date:2020/8/3 0003
* @time:15:31
* @description:no description
*/
public class DownUtil
{
// 定义下载资源的路径
private String path;
// 指定所下载的文件的保存位置
private String targetFile;
// 定义需要使用多少线程下载资源
private int threadNum;
// 定义下载的线程对象
private DownThread[] threads;
// 定义下载的文件的总大小
private int fileSize;
public DownUtil(String path, String targetFile, int threadNum)
{
this.path = path;
this.threadNum = threadNum;
// 初始化threads数组
threads = new DownThread[threadNum];
this.targetFile = targetFile;
}
public void download() throws Exception
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
// 得到文件大小
fileSize = conn.getContentLength();
conn.disconnect();
int currentPartSize = fileSize / threadNum + 1;
RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
// 设置本地文件的大小
file.setLength(fileSize);
file.close();
for (int i = 0; i < threadNum; i++)
{
// 计算每条线程的下载的开始位置
int startPos = i * currentPartSize;
// 每个线程使用一个RandomAccessFile进行下载
RandomAccessFile currentPart = new RandomAccessFile(targetFile,
"rw");
// 定位该线程的下载位置
currentPart.seek(startPos);
// 创建下载线程
threads[i] = new DownThread(startPos, currentPartSize,
currentPart);
// 启动下载线程
threads[i].start();
}
}
// 获取下载的完成百分比
public double getCompleteRate()
{
// 统计多条线程已经下载的总大小
int sumSize = 0;
for (int i = 0; i < threadNum; i++)
{
sumSize += threads[i].length;
}
// 返回已经完成的百分比
return sumSize * 1.0 / fileSize;
}
private class DownThread extends Thread
{
// 当前线程的下载位置
private int startPos;
// 定义当前线程负责下载的文件大小
private int currentPartSize;
// 当前线程需要下载的文件块
private RandomAccessFile currentPart;
// 定义已经该线程已下载的字节数
public int length;
public DownThread(int startPos, int currentPartSize,
RandomAccessFile currentPart)
{
this.startPos = startPos;
this.currentPartSize = currentPartSize;
this.currentPart = currentPart;
}
@Override
public void run()
{
try
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url
.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
InputStream inStream = conn.getInputStream();
// 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
inStream.skip(this.startPos);
byte[] buffer = new byte[1024];
int hasRead = 0;
// 读取网络数据,并写入本地文件
while (length < currentPartSize
&& (hasRead = inStream.read(buffer)) != -1)
{
currentPart.write(buffer, 0, hasRead);
// 累计该线程下载的总大小
length += hasRead;
}
currentPart.close();
inStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
测试方法(可脱离工具类):
public class Test {
private final static String path = "https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/1596438480944.png";
public static void test() throws IOException {
// (1)创建URL实例
URL url = new URL(path);
// (2)跟网络地址建立连接
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
int code = connection.getResponseCode();
String msg = connection.getResponseMessage();
System.out.println(code + ":" + msg);
//(3)交互
InputStream input = connection.getInputStream();
FileOutputStream output = new FileOutputStream("code/network/demo.png");
int a = -1;
while ((a = input.read()) != -1){
output.write(a);
}
// (4)关闭资源
input.close();
output.close();
connection.disconnect();
}
public static void main(String[] args) throws Exception {
// DownUtil downUtil = new DownUtil("https://glh508-blog-img.oss-cn-beijing.aliyuncs.com/1596438480944.png",
// "demo.png",4);
// downUtil.download();
test();
}
}
步骤:
(1)、创建URL对象;
(2)、与网络资源建立连接。用的是URLConnection的子类HttpURLConnection;对获得连接进行一些请求参数的操作。
(3)、获取输入流,对输入流进行写出操作;
(4)、关闭资源。
二、基于TCP的网络编程
端对端协议:A与B设备之间建立一条虚拟的网络链路。(用到Java提供的一个对象Socket)
三、基于UDP的网络编程
四、作业
五、UDP详解
一,TCP/IP协议栈中,TCP协议和UDP协议的联系和区别?
联系:
TCP和UDP是TCP/IP协议栈中传输层的两个协议,它们使用网络层功能把数据包发送到目的地,从而为应用层提供网络服务。
区别:
-
TCP是面向连接的传输。UDP是无连接的传输。
TCP保证数据按照发送顺序到达,UDP无法保证。
-
TCP是可靠性传输,而UDP则是不可靠传输。
UDP因为少了很多控制信息,所以传输速度比TCP速度快。
6. TCP适合用于传输大量数据,UDP适合用于传输小量数据。
-
举例: TCP的server和client之间通信就好比两个人打电话。UDP的server和client之间的通信就像两个人发电报或者发短信。
二,UDP通讯协议的特点:
-
将数据极封装为数据包,面向无连接。
每个数据包大小限制在64K中
3.因为无连接,所以不可靠
4. 因为不需要建立连接,所以速度快
5.udp 通讯是不分服务端与客户端的,只分发送端与接收端。
三,怎样来编写UDP?
发送数据步骤:
1.创建socket服务
2.创建数据包
3.将数据封装到数据包中,添加ip和端口以及数据
4.发送
5.关闭资源
接收数据步骤:
1.创建socket服务,并监听端口
2.创建数据包,用来接收数据
3.用socket接收数据到数据包中
4.从数据包中取出数据
5.关闭资源
四,代码实现UDP通信
1.客户端代码
1 import java.io.IOException;
2 import java.net.DatagramPacket;
3 import java.net.DatagramSocket;
4 import java.net.InetAddress;
5 import java.util.Scanner;
6
7 public class User {
8 static Scanner sc= new Scanner(System.in);
9 public static void main(String[] args) throws IOException {
10 //1.创建客户端套接字
11 DatagramSocket ds = new DatagramSocket();
12 //2.创建客户端发送数据包
13 while(true){
14 System.out.println("请输入要发送的信息:");
15 String info = sc.nextLine();
16 byte []buf =info.getBytes();
17 DatagramPacket dp = new DatagramPacket(buf, buf.length,
18 InetAddress.getByName("localhost"), 152);
19 //3.发送数据包
20 ds.send(dp);
21 //4.结束发送循环
22 if("886".equals(info)){
23 break;
24 }
25 }
26 //5.关闭套接字
27 ds.close();
28 }
29 }
2.服务端代码
1 import java.io.IOException;
2 import java.net.DatagramPacket;
3 import java.net.DatagramSocket;
4 import java.net.InetAddress;
5
6 public class Server {
7 public static void main(String[] args) throws IOException {
8 //1.创建服务端套接字
9 DatagramSocket ds = new DatagramSocket(152);//注意指定端口
10 //2.创建接受客户端信息的空数据包
11 while(true){
12 byte [] buf =new byte[1024];
13 DatagramPacket dp = new DatagramPacket(buf, buf.length);
14 //3.接受数据
15 ds.receive(dp);
16 //4.拆分数据
17 byte[] data = dp.getData();
18 //5.获取客户端IP和主机名
19 InetAddress ip = dp.getAddress();
20 String host = ip.getHostName();
21 //6.读取数据
22 String info = new String(buf,0,buf.length);
23 System.out.println("来自"+host+"的消息是:"+info);
24 ds.close();
25 //7.关闭套接字
26 }
27 }
28 }
CNAME验证
请将6Eaj2uriTt.yangxl.xyz使用CNAME解析到ziyuan.baidu.com
完成操作后请点击“完成验证”按钮。
为保持验证通过的状态,成功验证后请不要删除该DNS记录

浙公网安备 33010602011771号