java例题:实现多客户聊天

java 实现多客户端聊天(TCP)

1. 编程思想:

  1. 要想实现多客户端聊天,首先需要有多个客户端,而这些客户端需要随时发送消息和接受消息,所以收发消息需要放入不同的线程中。
  2. 多客户聊天并不是多个客户之间进行两两通信,而是需要所有客户端与服务端进行交互,再由服务端统一下发信息到其他参与聊天的客户端。

2. 代码实现:

2.1 实现专用于接收消息的子线程ReceiveThread

将接收消息和发送消息分为两个线程,其中将发送消息写入主线程中,开启新的线程用于接收消息。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReceiveThread extends Thread{

	private Socket socket; //私有的成员变量,套接字
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;//使用带缓冲区的字符输入流接收信息
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(true){
			try {
				System.out.println(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

2.2 客户端代码

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
	@SuppressWarnings("all")
	public static void main(String[] args) throws UnknownHostException, IOException {		
        //ip:需要连接的服务端所在的ip
        //端口:客户端连接的端口必须和服务端端口一致
		Socket socket = new Socket("192.168.*.*",8080);
		Scanner scan = new Scanner(System.in);
		new ReceiveThread(socket).start();
		//发送给服务端信息
		while(true ){
			PrintStream ps = new PrintStream(socket.getOutputStream());
			ps.println("一号:"+scan.next());		
		}
	}
}

注:

  1. 客户端代码可以在局域网下的多台电脑上运行,只需要将ip地址改为服务端的ip,就能够连接。

  2. 如果想要使用同台电脑完成一个服务端和两个客户端运行,进行测试多人聊天,可创建客户端2,使用本机ip

    Socket socket = new Socket("127.0.0.1",8080);
    Scanner scan = new Scanner(System.in);
    new ReceiveThread(socket).start();
    //发送给服务端信息
    while(true ){
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("二号:"+scan.next());		
    }
    

2.3 服务端接收和转发信息的线程ServerThread

服务端在每一个客户端进行连接时,都会产生一个线程,用于服务这个客户,负责接收该客户发送的信息,并转发到参与多人聊天的其他客户。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
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() {
		BufferedReader br = null;
		String str=null;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(true){
			try {
				str=br.readLine();
                //在服务端输出,可以监测到所有人的聊天信息。
				System.out.println(str);
				
				//发送到其他客户端
				Set<Entry<InetAddress, Socket>> entrySet = Server.map.entrySet();
				for (Entry<InetAddress, Socket> entry : entrySet) {
					InetAddress key = entry.getKey();
					Socket value = entry.getValue();
					if(socket.getInetAddress()!=key){
						PrintStream printStream = new PrintStream(value.getOutputStream());
						printStream.println(str);
					}
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

2.4 服务端代码

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;

public class Server {
	@SuppressWarnings("all")
    
	public static ConcurrentHashMap<InetAddress, Socket> map =new ConcurrentHashMap<>();
	public static void main(String[] args) throws IOException, InterruptedException {

		//创建服务端的ServerSocket
		ServerSocket server = new ServerSocket(8080);
		while(true){
            //接收到客户连接就创建一个对应的套接字
			Socket socket = server.accept();
            //获取该客户的ip
			InetAddress inetAddress = socket.getInetAddress();
			//将该客户的ip和套接字装入map集合
			map.put(inetAddress, socket);
            //创建新的线程服务该客户
			new ServerThread(socket).start();
		}		
	}
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值