第八章 网络编程


8.1、概述

计算机网络:是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系
统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统

网络编程:在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换

8.2、三要素

IP地址:是网络中设备的唯一标识,一般分两类:IPV4、IPV6

端口:设备上应用程序的唯一标识,常见的端口:8080、3306

协议:计算机网络中,连接和通信的规则被称为网络通信协议,常见的协议:UDP协议、TCP协议

8.3、UDP编程

UDP协议:用户数据报协议(User Datagram Protocol),无连接通讯协议,但不能保证传输数据完整性,常用于音频、视频、普通数据传输等

8.3.1、发送数据

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SendDemo {
	public static void main(String[] args) throws IOException {
		// 1.创建发送端套接字对象
		DatagramSocket ds = new DatagramSocket();
		// 2.创建数据并把数据打包
		byte[] bys = "Hello,World!".getBytes();
		DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 10086);
		// 3.从此套接字发送数据包
		ds.send(dp);
		// 4.关闭此数据包的套接字
		ds.close();
	}
}

8.3.2、接收数据

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveDemo {
	public static void main(String[] args) throws IOException {
		// 1.创建接收端套接字对象
		DatagramSocket ds = new DatagramSocket(10086);
		// 2.创建数据包用于接收数据
		byte[] bys = new byte[1024];
		DatagramPacket dp = new DatagramPacket(bys, bys.length);
		ds.receive(dp);
		// 3.解析数据包并把数据输出
		System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
		// 4.关闭此数据包的套接字
		ds.close();
	}
}

8.3.3、练习

  • 案例需求:

UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据才结束

UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

  • 代码实现:
// 发送端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SendDemo {
	public static void main(String[] args) throws IOException {
		DatagramSocket ds = new DatagramSocket();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		while ((line = br.readLine()) != null) {
			if ("886".equals(line)) {
				break;
			}
			byte[] bys = line.getBytes();
			DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 10086);
			ds.send(dp);
		}
		ds.close();
	}
}

// 接收端代码:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveDemo {
	public static void main(String[] args) throws IOException {
		DatagramSocket ds = new DatagramSocket(10086);
		while (true) {
			byte[] bys = new byte[1024];
			DatagramPacket dp = new DatagramPacket(bys, bys.length);
			ds.receive(dp);
			System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
		}
	}
}

8.4、TCP编程

TCP协议:传输控制协议 (Transmission Control Protocol),面向连接通讯协议、且可以保证传输数据完整性,常用于文件上传、文件下载、浏览网页等

8.4.1、发送数据

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 1.创建客户端的Socket对象
		Socket s = new Socket("127.0.0.1", 10086);
		// 2.获取输出流对象,写数据
		OutputStream os = s.getOutputStream();
		os.write("Hello,World!".getBytes());
		// 3.释放资源
		s.close();
	}
}

8.4.2、接收数据

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
	public static void main(String[] args) throws IOException {
		// 1.创建服务端的ServerSocket对象
		ServerSocket ss = new ServerSocket(10086);
		// 2.侦听要连接到此套接字并接受它
		Socket s = ss.accept();
		// 3.获取输入流对象,读数据
		InputStream is = s.getInputStream();
		byte[] bys = new byte[1024];
		int len = is.read(bys);
		String data = new String(bys, 0, len);
		System.out.println("数据是:" + data);
		// 4.释放资源
		s.close();
		ss.close();
	}
}

8.4.3、练习

  • 案例需求

客户端:数据来自于键盘录入,直到输入的数据是886,发送数据才结束

服务端:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

  • 代码实现:
// 客户端
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ClientDemo {
	public static void main(String[] args) throws IOException {
		Socket s = new Socket("127.0.0.1", 10086);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line;
		while ((line = br.readLine()) != null) {
			if ("886".equals(line)) {
				break;
			}
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		s.close();
	}
}

// 服务端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(10086);
		Socket s = ss.accept();
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String line;
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		ss.close();
	}
}

8.5、文件上传

8.5.1、单线程文件上传

客户端代码:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("127.0.0.1", 10086);
		// 封装文本文件的数据
		BufferedReader br = new BufferedReader(new FileReader("src\\ClientDemo.java"));
		// 封装输出流写出数据
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line;
		while ((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		// 告诉服务器上传结束
		s.shutdownOutput();
		// 接收服务器端的反馈
		BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String data = brClient.readLine();
		System.out.println("服务器反馈:" + data);
		// 释放资源
		br.close();
		s.close();
	}
}

服务端代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class ServerDemo {
	public static void main(String[] args) throws IOException {
		// 创建服务器Socket对象
		ServerSocket ss = new ServerSocket(10086);
		// 监听客户端的连接对象
		Socket s = ss.accept();
		// 获取上传文件随机名称
		String fileName = "src\\" + System.currentTimeMillis() + new Random().nextInt(999999) + ".java";
		// 保存客户端上传的数据
		BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileName));
		byte[] bys = new byte[1024];
		int len;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
		}
		// 给客户端发出反馈信息
		BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		bwServer.write("文件上传成功");
		bwServer.newLine();
		bwServer.flush();
		// 释放资源
		bos.close();
		ss.close();
	}
}

8.5.2、多线程文件上传

客户端代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("127.0.0.1", 10086);
		// 打开本地文件准备上传
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src\\ClientDemo.java"));
		BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
		byte[] bys = new byte[1024];
		int len;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
			bos.flush();
		}
		// 告诉服务器上传结束
		s.shutdownOutput();
		// 接收服务器端的反馈
		BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String data = brClient.readLine();
		System.out.println("服务器反馈:" + data);
		// 释放资源
		bis.close();
		s.close();
	}
}

服务端代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

class ServerThread implements Runnable {
	private Socket s;

	public ServerThread(Socket s) {
		this.s = s;
	}

	@Override
	public void run() {
		try {
			// 获取上传文件随机名称
			String fileName = "src\\" + System.currentTimeMillis() + new Random().nextInt(999999) + ".java";
			// 保存客户端上传的数据
			BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileName));
			byte[] bys = new byte[1024];
			int len;
			while ((len = bis.read(bys)) != -1) {
				bos.write(bys, 0, len);
			}
			// 给客户端发出反馈信息
			BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			bwServer.write("文件上传成功");
			bwServer.newLine();
			bwServer.flush();
			// 释放资源
			bos.close();
			s.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

public class ServerDemo {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(10086);
		while (true) {
			Socket s = ss.accept();
			ServerThread serverThread = new ServerThread(s);
			new Thread(serverThread).start();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38490457/article/details/107494885