分布式通信协议基础(分布式二)

版权声明:随意转载。 https://blog.csdn.net/dengjili/article/details/85568342

OSI七层网络模型与TCP/IP四层网络模型

例1

TCP协议中的三次握手和四次挥手

wireshark抓包分析http:https://blog.csdn.net/dengjili/article/details/85850267
在这里插入图片描述
滑动窗口
在这里插入图片描述
ACK 表示下一次期望收到的开始数据,window表示窗口大小,滑动窗口目的是控制发送速度,以免接收方的缓存不够大导致溢出,同时控制流量也可以避免网络拥塞。

TCP通信中的缓冲区

在这里插入图片描述
首先,对于TCP通信来说,每个TCP Socket的内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式及TCP的滑动窗口就是依赖于这两个独立的Buffer和该Buffer的填充状态。
接收缓冲区把数据缓存到内核,若应用进程一直没有调用Socket的read方法进行读取,那么该数据会一直被缓存在接收缓冲区内。不管进程是否读取Socket,对端发来的数据都会经过内核接收并缓存到Socket的内核接收缓冲区。
read索要做的工作,就是把内核接收缓冲区中的数据复制到应用层用户的Buffer里。

进程调用Socket的send发送数据的时候,一般情况下是讲数据从应用层用户的Buffer里复制到Socket的内核发送缓冲区,然后send就会在上层返回。换句话说,send返回时,数据不一定会被发送到对端。

单工,单向传输数据,对应java代码

服务端

public class ScoketServer {
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		
		try {
			// 启动一个应用
			serverSocket = new ServerSocket(8888);   
			// 等待缓冲区的数据,BIO模型
			Socket accept = serverSocket.accept();
			// 字节流转换为字符流
			BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));			
			System.out.println(br.readLine());
		} catch (IOException e) {
		} finally {
			// 关闭资源
			if (serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
				}
			}
		}
	}
}

客户端

public class ScoketClient {

	public static void main(String[] args) {

		Socket socket = null;
		try {
			socket = new Socket("localhost", 8888);
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			bw.write("hello 张三");
			// 强制发送缓存区数据,可能缓冲区数据不满
			bw.flush();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
				}
			}
		}
	}
}

双工,双向传输数据,对应java代码

服务端

public class ScoketServerDeplex {
	static ServerSocket serverSocket = null;
	public static void main(String[] args) {

		try {
			// 启动一个应用
			serverSocket = new ServerSocket(8888);
			new Thread(() -> {
				while (true) {
					Socket socket;
					try {
						socket = serverSocket.accept();
						DataInputStream dis = new DataInputStream(socket.getInputStream());
						DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
						// 读
						String serverData = dis.readUTF();
						System.out.println("服务端接收到数据:" + serverData);
						// 写
						dos.writeUTF("hello 李四");
						dos.flush();

						socket.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
			System.out.println("服务器启动成功...");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

客户端

public class ScoketClientDeplex {

	public static void main(String[] args) {

		Socket socket = null;
		try {
			socket = new Socket("localhost", 8888);
			DataInputStream dis = new DataInputStream(socket.getInputStream());
			DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
			
			// 发送
			dos.writeUTF("hello 张三");
			dos.flush();
			
			// 接收
			String serverData = dis.readUTF();
			System.out.println("客户端接收到数据:" + serverData);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
				}
			}
		}
	}
}

UDP通信

组播Multicas

服务端

扫描二维码关注公众号,回复: 4868769 查看本文章
public class MulticastServer {
	
	public static void main(String[] args) {
		// 组播ip地址: 224.0.0.0-239.255.255.255
		try {
			InetAddress group = InetAddress.getByName("224.8.8.8");
			MulticastSocket socket = new MulticastSocket();
			
			for (int i = 0; i < 10; i++) {
				String data = "Hello 李四";
				byte[] bytes = data.getBytes();
				socket.send(new DatagramPacket(bytes, bytes.length, group, 8888));
				TimeUnit.SECONDS.sleep(2);
			}
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

客户端

public class MulticastClient {
	
	public static void main(String[] args) {
		// 组播ip地址: 224.0.0.0-239.255.255.255
		try {
			InetAddress group = InetAddress.getByName("224.8.8.8");
			MulticastSocket socket = new MulticastSocket(8888);
			
			socket.joinGroup(group);
			
			byte[] buf = new byte[128];
			
			while (true) {
				DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);
				socket.receive(msgPacket);
				
				byte[] data = msgPacket.getData();
				String serverData = new String(data, 0, data.length);
				System.out.println("接收到服务器数据:" + serverData);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

猜你喜欢

转载自blog.csdn.net/dengjili/article/details/85568342