TCP案例之单聊与群聊

TCP案例之单聊与群聊

一、TCP案例之单聊

在基于TCP协议的单聊应用中,通常涉及客户端和服务器端的交互。

服务器端

  1. 建立服务器
    • 服务器端创建一个TCP Socket并绑定到一个特定的端口,开始监听来自客户端的连接请求。
  2. 接受连接
    • 服务器端接受客户端的连接请求,建立TCP连接。
  3. 接收消息
    • 服务器端接收客户端发送的消息数据。
  4. 处理消息
    • 服务器端处理接收到的消息,可以进行消息转发、存储、验证等操作。
  5. 发送响应
    • 服务器端可以向客户端发送响应,如确认消息接收、错误提示等。

客户端

  1. 建立连接
    • 客户端创建一个TCP Socket并连接到服务器端的IP地址和端口。
  2. 发送消息
    • 客户端向服务器端发送消息数据。
  3. 接收响应
    • 客户端接收服务器端的响应数据。
  4. 处理响应
    • 客户端处理接收到的响应,可以展示在界面上或者进行其他操作。
  5. 关闭连接
    • 客户端和服务器端在通信结束后关闭连接。

示例场景

  • Alice和Bob是两个用户,他们分别运行客户端应用程序。
  • 服务器端监听在特定端口上,等待客户端连接。
  • Alice连接到服务器端,发送一条消息给Bob。
  • 服务器端接收Alice的消息,转发给Bob。
  • Bob接收到消息后可以进行回复,服务器再将消息转发给Alice。

示例代码

客服端

java 复制代码
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {

	/**
	 * 知识点:TCP案例 之 优化单聊
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 9082);
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小雷:" + scan.next());
		}
		
	}
}

服务器端

java 复制代码
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(9082);
		
		Socket socket = server.accept();
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小杨:" + scan.next());
		}
		
	}
}

接收线程(相当于中转站)

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

public class ReceiveThread extends Thread{
	
	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
				String readLine = br.readLine();
				System.out.println(readLine);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
}

二、TCP案例之群聊

基于TCP协议的群聊应用涉及多个客户端与服务器之间的交互,实现了群组内的消息广播功能。

服务器端

  1. 建立服务器
    • 服务器端创建一个TCP Socket并绑定到一个特定的端口,开始监听来自客户端的连接请求。
  2. 接受连接
    • 服务器端接受客户端的连接请求,建立TCP连接。
  3. 加入群组
    • 客户端可以向服务器发送加入群组的请求,服务器更新群组成员列表。
  4. 接收消息
    • 服务器端接收客户端发送的消息数据。
  5. 消息广播
    • 服务器端将接收到的消息广播给所有群组成员。
  6. 处理退出
    • 客户端可以发送退出群组的请求,服务器更新群组成员列表并通知其他成员。

客户端

  1. 建立连接
    • 客户端创建一个TCP Socket并连接到服务器端的IP地址和端口。
  2. 加入群组
    • 客户端向服务器发送加入群组的请求。
  3. 发送消息
    • 客户端向服务器发送消息数据。
  4. 接收广播
    • 客户端接收服务器端广播的消息数据。
  5. 处理消息
    • 客户端展示接收到的消息数据。
  6. 退出群组
    • 客户端可以发送退出群组的请求。

示例场景

  • 服务器端维护一个群组成员列表,包括Alice、Bob、Charlie等用户。
  • Alice、Bob、Charlie分别连接到服务器端,加入群组。
  • Alice发送一条消息给所有群组成员。
  • 服务器端接收Alice的消息,将消息广播给Bob、Charlie等成员。
  • Bob和Charlie接收到消息后可以进行回复或者其他操作。
  • Bob决定退出群组,发送退出请求给服务器端。

示例代码

服务器端

java 复制代码
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {

	/**
	 * 知识点:TCP案例 之 群聊
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 7080);
		
		new ReceiveThread(socket).start();
		
		Scanner scan = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("小杨:" + scan.next());
		}
		
	}
}

服务器端:

java 复制代码
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;

public class Server {
	
	public static final ConcurrentHashMap<String, PrintStream> map = new ConcurrentHashMap<>();

	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(7080);
		
		while(true){
			
			Socket socket = server.accept();
			
			String ip = socket.getInetAddress().toString();
			PrintStream ps = new PrintStream(socket.getOutputStream());
			map.put(ip, ps);
			
			new ServerThread(socket).start();
		}
		
	}
}

服务器线程

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Map.Entry;
import java.util.Set;

public class ServerThread extends Thread{
	
	private Socket socket;
	
	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
			//接受当前客户端的消息
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
				String readLine = br.readLine();
				System.out.println(readLine);
				
				//发送给其他客户端消息
				Set<Entry<String,PrintStream>> entrySet = Server.map.entrySet();
				for (Entry<String, PrintStream> entry : entrySet) {
					String ip = entry.getKey();
					PrintStream ps = entry.getValue();
					
					if(!socket.getInetAddress().toString().equals(ip)){
						ps.println(readLine);
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}
}

接受线程:

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

public class ReceiveThread extends Thread{
	
	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
			while(true){
				String readLine = br.readLine();
				System.out.println(readLine);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
}

TCP群聊理解图

相关推荐
快乐肚皮几秒前
Spring Framework 6:核心升级特性
java·spring
&岁月不待人&14 分钟前
实现弹窗随键盘上移居中
java·kotlin
残*影21 分钟前
Spring Bean的初始化过程是怎么样的?
java·后端·spring
黎䪽圓27 分钟前
【Java多线程从青铜到王者】单例设计模式(八)
java·开发语言·设计模式
Java技术小馆27 分钟前
面试被问 Java为什么有这么多O
java·后端·面试
崔lc44 分钟前
Springboot项目集成Ai模型(阿里云百炼-DeepSeek)
java·spring boot·后端·ai
Dream Algorithm44 分钟前
中国移动6周年!
网络·架构·信息与通信
菜鸟康1 小时前
C++实现分布式网络通信框架RPC(2)——rpc发布端
分布式·网络协议·rpc
异常君1 小时前
Java 中 String 的不可变性与 final 设计:核心原理与性能实践
java·面试·代码规范