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();
}
}
}