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群聊理解图

相关推荐
qq_4419960518 分钟前
Mybatis官方生成器使用示例
java·mybatis
巨大八爪鱼24 分钟前
XP系统下用mod_jk 1.2.40整合apache2.2.16和tomcat 6.0.29,让apache可以同时访问php和jsp页面
java·tomcat·apache·mod_jk
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田2 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
长安11082 小时前
前后端、网关、协议方面补充
网络
魔道不误砍柴功4 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
枫叶_v4 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
wclass-zhengge4 小时前
SpringCloud篇(配置中心 - Nacos)
java·spring·spring cloud
路在脚下@4 小时前
Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点和适用场景
java·spring boot·servlet