欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室

程序员文章站 2022-05-25 21:16:40
...

1. 网络编程概述

1.1 计算机网络

将独立的,分散的计算机系统(手机,电脑)通过线路,通信设备(路由器,交换机)连接起来,由软件来实在资源共享,信息传递的系统。

1.2 网络模型

  • OSI开放式系统互联。国际标准组织制定了OS七层网络模型(Open System Interconnection)模型
  • OSI七层网络模型
    物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

1.3 协议

  • 事先规定好的通信规则
  • 协议分类
    • 公有:IP、HTTP、UDP
    • 私有: JDBC连接数据库的总协议

网络层:IP
传输层:UDP、TCP
应用层:FTP(上传下载(响应成功后不断开))、HTTP(宣传性网站(响应成功后断开))、HTTPS

1.4 IP地址

  • IP地址:标识网络上的唯一一台计算机
  • IP地址分为两个版本:IPv4(32位二进制)、IPv6(128位二进制)

1.5 端口

  • 范围:0-65535
  • (0-1024)是预留的端口号,已经被某些服务器占用

1.6域名解析

解析成IP地址
localhost(www.163.com) --> 127.0.0.1(72.1.1.1)

2. Java中的网络编程

2.1 UDP通信——写信

  • 不需要创建连接
  • 通过发送数据包通信 每个数据包最大64kb
  • 不可靠的传输机制
  • 传输速度
  • 追求速度快,可靠性要求不高的场景下 — 视频聊天

2.2 TCP通信——打电话

  • 需要先创建连接。并且在创建连接的过程中,需要经过三次握手
  • 底层通过 发送数据,数据大小没有限制
  • 可靠的传输机制 – 丢包重发 包的顺序的保障
  • 传输速度相对较
  • 对于速度要求不太高,但是对可靠性要求比较高的场景下 - 文件上传 下载

eg:
要先启动接收端,再启动发送端
达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室
达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室
因为TCP在通信的过程中是需要创建连接的,

  • 连接的发起者称为客户端
  • 监听端口等待被连接的一端称为服务端
    达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室
    服务端:
    达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室
    客户端:
    达内javaSE_day14学习笔记 —— 网络编程、模拟会话聊天室

案例:实现文件上传服务器

/**
 * 实现上传功能
 */
public class DemoUploadServer {
	public static void main(String[] args) throws IOException{
		//1.创建套接字对象
		ServerSocket serverSocket = new ServerSocket(4444);
		Socket socket = serverSocket.accept();		
		//2.获取输入流对象,解析数据
		InputStream inputStream = socket.getInputStream();
		byte[] b = new byte[1];
		String str = "";
		while(!str.endsWith("\r\n")) {
			inputStream.read(b);
			str += new String(b);
		}
		//str="11\r\n";
		int fileNameLen = Integer.parseInt(str.substring(0,str.length()-2)); //[0,2)
		byte[] fileNameArr = new byte[fileNameLen];
		inputStream.read(fileNameArr);
		//文件名
		String fileName = new String(fileNameArr);		
		byte[] b2 = new byte[1];
		String str2 = "";
		while(!str2.endsWith("\r\n")) {
			inputStream.read(b2);
			str2 += new String(b2);
		}
		int fileLen = Integer.parseInt(str2.substring(0,str2.length()-2));
		byte[] fileArr = new byte[fileLen];
		inputStream.read(fileArr);		
		//3.创建文件的输出流,把数据文件的数据(byte),写到upload文件夹下,文件夹名为原数据文件的名字
		FileOutputStream fileOut = new FileOutputStream("upload/"+fileName);
		fileOut.write(fileArr);
		fileOut.close();		
		//4.使用输出流响应客户端的请求“上传成功!”
		OutputStream out = socket.getOutputStream();
		PrintWriter pWriter = new PrintWriter(out);//可以放字符流和字节流
		pWriter.println("上传成功!");//ln换行表示输入输出流结束
		pWriter.flush();//把没满的数据从缓冲区中推出来		
		//5.关闭流,关闭套接字对象
		pWriter.close();
		socket.close();
		serverSocket.close();
	}
}
/**
 * 实现上传功能
 */
public class DemoUploadClient {
	public static void main(String[] args) throws IOException {
		//1.创建套接字对象
		Socket socket = new Socket("127.0.0.1",4444);		
		//2.使用输出流输入数据文件内容
		OutputStream outputStream = socket.getOutputStream();
				
		//11 表示数据文件的文件名的长度(为了不浪费内存,也防止丢了数据);  \r回车  \n换行 ;  read_v1.txt表示传递给服务器的文件名 ;   100表示文件长度;    代码修正...表示文件内容 
		//[11\r\nread_v1.txt100\r\n代码修正...]
		File file = new File("read_v1.txt");
		//当前文件名长度
		outputStream.write((file.getName().getBytes().length+"\r\n").getBytes());
		//文件名
		outputStream.write(file.getName().getBytes());
		//文件长度
		outputStream.write((file.length()+"\r\n").getBytes());
		//写文件内容
		FileInputStream fileIn = new FileInputStream(file);
		byte[] buff = new byte[(int) file.length()];
		fileIn.read(buff);
		fileIn.close();
		outputStream.write(buff);		
		//5.接收服务器的响应
		InputStream inputStream = socket.getInputStream();
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));//字节流转换为字符流
		String msg = bufferedReader.readLine();
		System.out.println(msg);		
		//6.close()
		outputStream.close();
		inputStream.close();
		bufferedReader.close();
		socket.close();
	}
}

练习:模拟会话聊天室

v1:
代码修正
1.定义成员变量套接字
2.在构造方法中初始化
3.start方法处理读写
4.main方法创建对象,调用start方法

客户端:

public class Client {
	private Socket socket;
	public Client(){
		try {
			socket = new Socket("localhost",5555);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void start() throws IOException {
		//获取输出流,写信息
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os);
		pw.println("啦啦啦");
		pw.flush();
		
		//获取输入流,读信息
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine();
		System.out.println(msg);		

		//关闭流,关闭套接字
		br.close();
		socket.close();
	}
	public static void main(String[] args) throws IOException {
		Client client = new Client();
		client.start();
	}
}

服务端:

public class Server {
	ServerSocket serverSocket;
	Socket socket;
	public Server() throws IOException {
		serverSocket = new ServerSocket(5555);
		socket = serverSocket.accept();
	}
	public void Start() throws IOException {
		//获取输入流对象,读客户端的数据
		InputStream is = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String msg = br.readLine();
		System.out.println(msg);
		
		//处理后的结果通过输出流,写出去
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os);
		pw.println(msg);
		pw.flush();
		
		//关闭流,关闭套接字对象
		br.close();
		pw.close();
		socket.close();
		serverSocket.close();
	}
	public static void main(String[] args) throws IOException {
		Server server = new Server();
		server.Start();
	}
}

v2:
控制台一对一会话
在客户端实现接收控制台输入

在v1的基础上,将客户端的写信息模块改进为控制台输入。

//客户端
//获取输出流,写信息
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os);
		Scanner scanner = new Scanner(System.in);
		System.out.println("input:");
		String str = scanner.next();
		pw.println(str);
		pw.flush();

v3:
一个客户端和服务器多次会话
客户端使用while循环输入
服务器端使用while循环接收数据

在v2的基础上,将服务端中的start() 处理读写的方法改进到while循环中。

//服务端
public void Start() throws IOException {
		Socket socket = serverSocket.accept();
		OutputStream os = null;
		InputStream is = null;
		PrintWriter pw = null;
		BufferedReader br = null;
		try {
			while(true) {
				//获取输入流对象,读客户端的数据
				is = socket.getInputStream();
				br = new BufferedReader(new InputStreamReader(is));
				String msg = br.readLine();				
				System.out.println(msg);
				msg+="好的呢";
				
				//处理后的结果通过输出流,写出去
				os = socket.getOutputStream();
				pw = new PrintWriter(os);
				pw.println(msg);
				pw.flush();
			}
		}catch(IOException e){
			e.printStackTrace();
		}finally {		
			//关闭流,关闭套接字对象
			br.close();
			pw.close();
			socket.close();
			serverSocket.close();
		}
	}
相关标签: javaSE实训笔记