socket多线程通信。

1.功能:通过socket实现多个人群聊、私聊的功能;效果如图。


2.java代码

服务器端:

/**
 * FileName:ChatServer.java
 * @author zhanggw
 * @date 2018年1月26日 下午10:04:44
 */
package com.kenick.chat;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 聊天服务器启动程序
 * @author zhanggw
 * @date 2018年1月26日 下午10:04:44
 */
public class ChatServer {
    // 存储所有服务器和客户端的socket连接
    public static Map<String,Socket> clientMap = Collections.synchronizedMap(new HashMap<String, Socket>());
    
    public static void main(String[] args) {
        ServerSocket serverSocket  = null;
        try {
            // 服务器启动,绑定本地端口5555
            serverSocket = new ServerSocket(5555);
            System.out.println("启动服务器完成!");
            
            // 开始不断接受客户端socket连接
            while(true){
                Socket clientSocket = serverSocket.accept();
                new Thread(new ChatServerProcessThread(clientSocket)).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * FileName:ChatServerProcessThread.java
 * @author zhanggw
 * @date 2018年1月26日 下午10:05:12
 */
package com.kenick.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Iterator;
import java.util.Set;

/**
 * 聊天服务器多线程处理类
 * @author zhanggw
 * @date 2018年1月26日 下午10:05:12
 */
public class ChatServerProcessThread implements Runnable{
    private Socket clientSocket;  // 与客户端的socket连接
    private BufferedReader clientBufferedReader; // 封装clientSocket
    
    public ChatServerProcessThread(Socket clientSocket) throws Exception{
        this.clientSocket = clientSocket;
        this.clientBufferedReader = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
    }

    @Override
    public void run() {
        String content = ""; // 接受的内容
        try {
            while((content=this.clientBufferedReader.readLine())!=null){
                try {
                    String[] clientArray = content.split(":");
                    String sendId = clientArray[0]; // 发送人id
                    String receiveId = clientArray[1]; // 接收人id
                    String sendMsg = clientArray[2]; // 发送内容
                    
                    if("register".equals(receiveId)){
                        // 注册并存储建立的socket连接
                        ChatServer.clientMap.put(sendId, this.clientSocket);
                    }else if("all".equals(receiveId)){
                        // 群聊,发送给所有人
                        Set<String> keySet = ChatServer.clientMap.keySet();
                        Iterator<String> keyIterator = keySet.iterator();
                        while(keyIterator.hasNext()){
                            String clientId= keyIterator.next();
                            if(!sendId.equals(clientId)){
                                Socket clientSocket = ChatServer.clientMap.get(clientId);
                                PrintStream ps = new PrintStream(clientSocket.getOutputStream());
                                ps.println(sendId+":"+sendMsg);
                                ps.flush();
                            }
                        }
                    }else{
                        // 私聊,发送给指定人
                        Set<String> keySet = ChatServer.clientMap.keySet();
                        Iterator<String> keyIterator = keySet.iterator();
                        while(keyIterator.hasNext()){
                            String clientId= keyIterator.next();
                            if(clientId.equals(receiveId)){
                                Socket clientSocket = ChatServer.clientMap.get(clientId);
                                PrintStream ps = new PrintStream(clientSocket.getOutputStream());
                                ps.println(sendId+":"+sendMsg);
                                ps.flush();
                            }
                        }
                    }
                } catch (Exception e) {
                    // 暂时隐去异常处理
                    //e.printStackTrace();
                }
            }
        } catch (IOException e) {
            // 暂时隐去异常处理
            // e.printStackTrace();
        }
    }
}
客户端:

/**
 * FileName:ChatClient.java
 * @author zhanggw
 * @date 2018年1月26日 下午10:18:53
 */
package com.kenick.chat;

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

/**
 * 聊天客户端启动程序
 * @author zhanggw
 * @date 2018年1月26日 下午10:18:53
 */
public class ChatClient {
    public static void main(String[] args) {
        try {
            String content = null; // 接收从命令行输入的信息
            String clientId = "anonymous"; // 默认账号
            
            Socket serverSocket = new Socket("127.0.0.1",5555);
            new Thread(new ChatClientProcessThread(serverSocket)).start();
            
            PrintStream ps = new PrintStream(serverSocket.getOutputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            
            System.out.println("注册你的账号:");
            if((content = br.readLine())!=null){
                if(!"".equals(content)){
                    clientId = content;
                    System.out.println("账号注册成功!账号ID:"+clientId);
                }else{
                    clientId = clientId+System.currentTimeMillis();
                    System.out.println("账号未注册成功,使用匿名账号:"+clientId);
                }
                ps.println(clientId+":register"+":newAccount");
                ps.flush();
            }
            
            // 开始循环接收输入信息,并发送给服务器
            while((content=br.readLine())!=null){
                ps.println(clientId+":"+content);
                ps.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
 * FileName:ChatClientProcessThread.java
 * @author zhanggw
 * @date 2018年1月26日 下午10:19:36
 */
package com.kenick.chat;

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

/**
 *  聊天客户端多线程处理类
 * @author zhanggw
 * @date 2018年1月26日 下午10:19:36
 */
public class ChatClientProcessThread implements Runnable{
    private Socket serverSocket; // 与服务器的socket连接
    private BufferedReader serverReader; // 对serverSocket的封装
    
    public ChatClientProcessThread(Socket serverSocket) throws Exception{
        this.serverSocket = serverSocket;
        this.serverReader = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
    }

    @Override
    public void run() {
        String content = null;
        try {
            while((content=this.serverReader.readLine())!=null){
                System.out.println(content);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                this.serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}



猜你喜欢

转载自blog.csdn.net/leadseczgw01/article/details/79180342