一、网络编程概述:
计算机网络:
网络模型(OSI开放式系统互联。国际标准组织制定了OS七层网络模型I(Open System Interconnection)模型)
OSI七层网络模型:
物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
协议:事先规定好的通信规则
协议分类:共有的,私有的
网络层:ip
传输层:udp,tcp
应用层:ftp http https。。。
IP地址
IP地址:表示网络上的唯一一台计算机
IP地址分为两个版本:
IPv4 IPv6
端口:0-65535 (0-1024)预留的
域名解析:localhost(www.163.com):127.0.0.1(72.1.1.1)
java中的网络编程
1.UDP通信 -- 写信
不需要创建连接
通过发送数据包通信 每个数据包最大64KB
不可靠的传输机制
传输速度比较快
追求速度快 可靠性要求不高的场景下 - 视频聊天
2.TCP通信 -- 打电话
需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手
底层通过 流 发送数据 数据没有大小限制
可靠的传输机制 - 丢包重发 包的顺序的保障
传输速度相对比较慢
对于速度要求不太高 但是对可靠性要求比较高的场景下 - 文件上传 下载
因为TCP在通信的过程中是需要创建连接的,连接的发起者称为客户端,监听端口等待被连接的一端称为服务端
🔺UDP编程:实例代码:
/**
* UDP编程
* @author 陶沅玱
* 发送端
*/
public class TestSend {
public static void main(String[] args) throws IOException {
//1.创建套接字对象
DatagramSocket ds = new DatagramSocket();
//2.发送信息
// 要发送的信息 包括 str内容、ip、端口号
String str = "hello";
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length());
dp.setSocketAddress(new InetSocketAddress("localhost", 6666));
ds.send(dp);
//3.关闭套接字对象
ds.close();
}
}
/**
* UDP编程
* @author 陶沅玱
* 接收端
*/
public class TestReveive {
public static void main(String[] args) throws IOException {
// Socket编程(套接字)
//1.创建套接字对象(端口号)
DatagramSocket ds = new DatagramSocket(6666);
//2.使用数据包对象来接受数据
byte[] data = new byte[1024];
DatagramPacket dp = new DatagramPacket(data, data.length);
//接收数据
ds.receive(dp);//当程序执行到这一步的时候,程序就自动暂停,等待TestSend类将数据发送过来,再执行下一步
//dp.getData(), 接收到的数据
//0, 表示从第0个位置开始
//dp.getLength() //表示发送过来的字符串的个数
String str = new String(dp.getData(), 0, dp.getLength());
System.out.println(str);
//3.关闭Socket对象
ds.close();
}
}
🔺TCP编程:
案例一:
/**
* TCP编程
* @author 陶沅玱
* 服务器端
*/
public class TestServer {
public static void main(String[] args) throws IOException {
//1.创建套接字对象
ServerSocket ss = new ServerSocket(8888);
//2.调用accept方法来接受请求
System.out.println("等待客户端的请求");
Socket socket = ss.accept();
System.out.println("已经接受到客户端的请求");
//3.获取输入流对象,读客户端的数据
InputStream in = socket.getInputStream();//字节流
//把字节流转换成字符流
BufferedReader br = new BufferedReader(
new InputStreamReader(in));
String str = br.readLine();
System.out.println(str);
//4.把处理后的结果通过输出流,写出去(给客户端)
str = str + "处理完成!";
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.println(str);
pw.flush();
//5.关闭流,关闭套接字对象
pw.close();
os.close();
br.close();
in.close();
socket.close();
ss.close();
}
}
/**
* TCP编程
* @author 陶沅玱
* 客户端
*/
public class TestClient {
public static void main(String[] args) throws IOException {
//1.创建套接字对象
Socket socket = new Socket("localhost", 8888);
//2.获取输出流,写信息
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.println("hello");
pw.flush();
System.out.println("Client 2");
//3.获取输入流读信息
InputStream in = socket.getInputStream();//字节流
//把字节流转换成字符流
BufferedReader br = new BufferedReader(
new InputStreamReader(in));
String str =br.readLine();
System.out.println(str);
System.out.println("Client 3");
//4.关闭流
System.out.println("Client 4");
br.close();
pw.close();
os.close();
}
}
案例二:实现 文件 上传服务器
/**
* 实现 文件 上传服务器
* 代码运行流程: Server1-> Client1,2 ->Server2,3,4 ->client3 -> Server5,client4
* @author 陶沅玱
*
*/
public class TestUploadServer {
public static void main(String[] args) throws IOException {
//1.创建套接字对象
ServerSocket serverSocket = new ServerSocket(4444);
//2.使用accept()方法接收客户端数据
Socket socket = serverSocket.accept();
//InputStream,并对数据进行解析 [11\r\nread_v1.txt5\r\nhello]byte类型的数组
InputStream is = socket.getInputStream();
//2.1解析到文件名的长度
String str = "";
byte[] b1 = new byte[1]; //一个字节一个字节获取
while(!str.endsWith("\r\n")) {
is.read(b1);
str += new String(b1);
}
//运行完: str = "11\r\n";
//获取到文件名的长度
int fileNameLength = Integer.parseInt(str.substring(0, str.length()-2));
//2.2解析到文件名
//通过文件名的长度直接获取到文件名
byte[] fileNameArr = new byte[fileNameLength];
//读取到文件名,并存储再b2数组中
is.read(fileNameArr);
//将文件名转换成字符串模式
String fileName = new String(fileNameArr);
//fileName = "read_v1.txt";
//2.3解析出文件内容长度
String str2 = "";
byte[] b2 = new byte[1];
while(!str2.endsWith("\r\n")) {
is.read(b2);
str2 += new String(b2);
}
//str2 = "5\r\n";
//获取到文本内容的长度
int fileTextLength = Integer.parseInt(str2.substring(0, str2.length()-2));
//2.4解析到文本内容
byte[] fileTextArr = new byte[fileTextLength];
is.read(fileTextArr);
String fileText = new String(fileTextArr);
// fileText = "hello";
//3.服务器进行处理:创建文件的输出流,把数据文件的数据(byte)写道upload文件夹下,文件名为原来数据文件的名字
//从程序到文件
FileOutputStream fos = new FileOutputStream("upload/" + fileName);
fos.write(fileTextArr);
fos.close();
//4.服务器响应:使用输出流完成对客户端的响应
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.println("上传完成!");
pw.flush();
//5.关闭流
pw.close();
os.close();
is.close();
socket.close();
}
}
------------------------------------------------------------------
public class TestUploadClient {
public static void main(String[] args) throws IOException {
//1.创建套接字对象 (ip, 端口号)
Socket socket = new Socket("localhost", 4444);
//2.从客户端到服务器 输出流输出数据文件内容
OutputStream os = socket.getOutputStream();
/*
* [11\r\nread_v1.txt5\r\nhello]
* 11表示数据文件的文件名的长度
* read_v1.txt 表示文件名
* 5表示文件字节大小
* hello表示文件中的内容
*/
File file = new File("testUploadClient.txt");
if(!file.exists()) {
file.createNewFile();
}
//输出文件名的长度
os.write((file.getName().length() + "\r\n").getBytes()); //11\r\n
System.out.println("-------------");
String s = new String((file.getName().length() + "\r\n").getBytes());
System.out.println(s);
//输出文件的名称
os.write(file.getName().getBytes()); //read_v1.txt
//输出文件内容的长度
os.write(((int)file.length() + "\r\n").getBytes()); //5\r\n
//获取到文件中的内容
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[(int)file.length()];
fis.read(b);
fis.close();
//输出文件中的内容
os.write(b); //hello
//3.接收到服务器的回复
InputStream is = socket.getInputStream();//字节流
//把字节流转换成字符流
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
System.out.println(br.readLine());
//4.关闭流
br.close();
is.close();
os.close();
socket.close();
}
}