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

相关推荐
小堃学编程19 分钟前
计算机网络(十) —— IP协议详解,理解运营商和全球网络
网络·tcp/ip·计算机网络
ok!ko1 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2402_857589361 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰2 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没2 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
IPFoxy6663 小时前
探索路由器静态IP的获取方式
网络·智能路由器
编程、小哥哥3 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
menge23333 小时前
VLAN:虚拟局域网
网络·智能路由器
GZ_TOGOGO3 小时前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
小鹿( ﹡ˆoˆ﹡ )3 小时前
探索IP协议的神秘面纱:Python中的网络通信
python·tcp/ip·php