基于java的聊天室/群发控制台程序

java聊天室

  1、概述

     基于tcp协议的,由一个服务器和多个客户端组成,一个客户端发送消息,其他所有客户端都能接收到消息。在服务器端设置一个线程监听客户端发来的请求(消息),并且向所有的客户端响应。每个客户端也有一个线程用来接收服务器端的请求。

  2、代码如下

  

public class Client {
    public static void main(String[] args) throws  IOException {
        //创建套接字
        Socket socket = new Socket("localhost",81);
        //获取套接字的输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //启动线程监听接收服务器端的消息
        new Thread(new ClientMessage(socket)).start();
        Scanner sc = new Scanner(System.in);
        //客户端发送消息
        while(true){
            String msg = sc.nextLine();
            if("exit".equals(msg)){
                break;
            }
            byte[] b = msg.getBytes();
            bos.write(b, 0, b.length);
            bos.flush();
        }
        bos.close();
        socket.close();
    }
}

class ClientMessage implements Runnable{
    private Socket socket;
    
    public ClientMessage(Socket socket) {
        super();
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            byte[] b = new byte[1024*8];
            while(true){
                int i = bis.read(b);
                if(i == -1){
                    break;
                }
                String msgFromServer = new String(b,0,i);
                System.out.println(msgFromServer);
            }
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
}
public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket s = new ServerSocket(81);// 创建服务器套接字,指定端口号
		List<Socket> sockets = new ArrayList<Socket>();
		System.out.println("服务器启动了");
		int i = 0;
		for (; i <= 100; i++) {// 可以有100个客户端
			// accept()是一个阻塞方法,如果客户端没有请求到来,该方法就不会执行。请求到达后立即产生一个Socket对象
			// 侦听并接收到此套接字的连接
			Socket socket = s.accept();
			// 输出该套接字的字符串格式
			System.out.println(socket);
			sockets.add(socket);
			// 启动线程用来接收消息并且群发
			new Thread(new ChatMessage(socket, sockets)).start();
		}
	}
}
class ChatMessage implements Runnable {
	private Socket socket;
	private List<Socket> sockets;

	public ChatMessage(Socket socket, List<Socket> sockets) {
		super();
		this.socket = socket;
		this.sockets = sockets;
	}

	@Override
	public void run() {
		try {
			// 获取当前socket的输入流
			BufferedInputStream bis = new BufferedInputStream(
					socket.getInputStream());
			byte[] b = new byte[1024];
			String msg = "";
			while (true) {
				int i = bis.read(b);
				if (i == -1) {
					break;
				}
				//获取客户端的消息
				msg = new String(b, 0, i);
				//群发
				for (Socket s : sockets) {
					out(s, socket.getInetAddress().getHostName() + ":" + msg);
				}
			}
		} catch (IOException e) {
		}
	}

	private void out(Socket s, String msg) {
		try {
			BufferedOutputStream bos = new BufferedOutputStream(
					s.getOutputStream());
			byte[] b = msg.getBytes();
			bos.write(b, 0, b.length);
			bos.flush();
		} catch (IOException e) {

		}
	}
}

  

  3、总结

    首先创建服务器对象ServerSocket,并指定端口号,端口不能被占用。然后调用其accept()方法侦听并接收到此套接字的连接。这是服务器的准备工作。客户端需要创建套接字指定ip和端口号确定对应的服务器。

    

  

 

posted on 2016-10-27 22:43  wantcrazy  阅读(1565)  评论(0编辑  收藏  举报

导航