`
bluethink
  • 浏览: 97929 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用Socket实现广播聊天室

    博客分类:
  • JAVA
阅读更多
首先说明的是,本帖中的例子是来自网上的一个例子,经过了优化后的结果

实现以下功能:
1.在服务端提示所有客户端发来的消息以及当前的在线人数
2.服务端自动转发新上线用户的IP端口号消息给所有用户(当前用户除外)
3.服务端自动转发当前客户发给其他客户的消息
4.服务端自动转发离线客户的消息
5.服务端接收客户端的断开连接消息,可以断开当前连接
6.客户端连接指定的服务端端口
7.客户端向服务发出普通消息
8.客户端向服务端发出断开连接消息

目前只能实现群聊功能,还无法实现私聊

比如目前有ABC三个用户连接到服务端S,客户端都给服务端发消息,服务端都把在收到的消息广播给其他客户端

客户端代码:
import java.io.BufferedReader;   
import java.io.InputStreamReader;   
import java.io.PrintWriter;   
import java.net.Socket;   
import java.util.concurrent.ExecutorService;   
import java.util.concurrent.Executors;
import java.util.*;

public class ChatClient {   
    private static final int PORT = 8888;   
    private static ExecutorService exec = Executors.newCachedThreadPool();   
	private String userId; //用户ID:使用客户端的IP+端口
  
    public static void main(String[] args) throws Exception {   
        new ChatClient();
    }
  
    public ChatClient() {
		Socket socket = null;
		String msg;

        try {
            socket = new Socket("localhost", PORT);
			//客户端连接到服务端之后,启动一个线程用于接收命令行输入,并且发送到服务端
            exec.execute(new Sender(socket));
			userId = socket.getInetAddress() + ":"+socket.getLocalPort();

            println("[" + userId + "] 您好,欢迎来到阿飞聊天室!");
			
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));   
            
            while (null != (msg = br.readLine())){
					println(msg);
            }
			
        } catch (Exception e) { }
    }
  
    /**  
     * 客户端线程获取控制台输入消息,并且向服务发送消息
     */
    static class Sender implements Runnable {
        private Socket socket;
  
        public Sender(Socket socket) {
            this.socket = socket;
        }
  
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));   
                PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);   
                String msg;

                while (true) {					
					
					//如果用户在命令行中按回车或输入空信息,则不发送到服务端
                    msg = br.readLine();
					if (msg.length()==0){
						print(socket.getLocalPort()+":>");
					}else{
						pw.println(msg);
						continue;
					}
  
					//客户端发bye退出
                    if (msg.trim().equals("bye")) {
                        pw.close();
                        br.close();
                        break;   
                    }
					
					//测试消息
					if (msg.equals("broadcast")){						
						msg = "这是来自"+socket.getInetAddress() + ":"+socket.getLocalPort() + " 的测试消息";
						pw.println(msg);	
					}
                }
				pw.close();
                br.close();
				socket.close();
				exec.shutdownNow();
            } catch (Exception e) {
                e.printStackTrace();   
            }
        }
    }

	public static void print(Object o){
		System.out.print(o);
	}

	public static void println(Object o){
		System.out.println(o);
	}
}  


服务端代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;   
import java.io.PrintWriter;   
import java.net.ServerSocket;   
import java.net.Socket;   
import java.util.ArrayList;   
import java.util.List;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ChatServer {
	// 端口号
    private static final int PORT = 8888; 

	//创建一个线程安全的的Socket列表,保存Socket对象
    private static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());

	//线程池服务对象
    private ExecutorService exec;   
    private ServerSocket server;
  
    public static void main(String[] args) {   
        new ChatServer();   
    }   
	
    public ChatServer() {
        try {
            server = new ServerSocket(PORT);

			//启动一个线程池
            exec = Executors.newCachedThreadPool();
            println("阿飞聊天室服务器已启动,监听 "+server.getInetAddress()+":"+server.getLocalPort() +" 端口");   
  
            Socket client = null;
            while (true) {
				//接收客户连接,该套接字将被添加到Socket列表列表中,并且创建一个新的服务线程
                client = server.accept(); 
                socketList.add(client);	
                exec.execute(new ChatTask(client));   
            }   
        } catch (IOException e) {   
            e.printStackTrace();
        }
    }
  
   //为客户端服务的线程类,负责收发该socket对象的输入和输出信息
   class ChatTask implements Runnable {
        private Socket socket;
        private BufferedReader bufferReader;
        private PrintWriter writer;
        private String msg;
		private int isClosed=0;
		private String userId; //用户ID:使用客户端的IP+端口
  
        public ChatTask(Socket socket) throws IOException {
            this.socket = socket;
            bufferReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));   
			userId = this.socket.getInetAddress() +":"+this.socket.getPort();
            msg = "[" + userId + "]进入聊天室!当前聊天室有"  
                    + socketList.size() + "人";
  
            sendMessage(socket.getPort());//给所有人发消息
        }
  
        public void run() {
            try {
                while ( null != (msg = bufferReader.readLine())){
					
					//服务端收到bye,关闭与该用户的连接
                    if (msg.trim().equals("bye")) {
                        socketList.remove(socket);

                        msg = "[" + userId + "]离开聊天室!当前聊天室有" + socketList.size() + "人";                        
                        sendMessage(socket.getPort()); //给别人发
                        break;
                    } else {
                        msg = "[" + userId+ "]说: " + msg;
                        sendMessage(socket.getPort()); //给别人发
                    }

					try{
						Thread.sleep(10);
					}catch(Exception e){
						e.printStackTrace();
					}
                }
				//关闭服务,关闭的同时也就关闭了InputStream和outputStream,因此不必在上面关闭pw 和  br
				socket.close();
				bufferReader=null;
				writer=null;				
            } catch (IOException e) {
                //e.printStackTrace();
            }
        }   
  
        /**  
         * 群发消息给聊天室的其他人
         */  
        private void sendMessage(int selfPort) throws IOException {   //Socket selfSocket,boolean toSelf
            println(msg);
            for (Socket client : socketList) {
				if (client.getPort() != selfPort){
					writer = new PrintWriter(client.getOutputStream(), true);
					writer.println(msg);
				}
            }
        }
    }

	public static void println(Object o){
		System.out.println(o);
	}
}  


启动了服务端之后,然后再启动两个或多个客户端,在每个客户端窗口里直接输入要发送的消息按回车,该信息即可被广播到其他的客户端窗口

服务端图片:


客户端图片:




  • 大小: 45.6 KB
  • 大小: 35 KB
  • 大小: 33.7 KB
分享到:
评论

相关推荐

    Socket实现简单聊天室

    在这个“Socket实现简单聊天室”的项目中,我们可以通过Socket来构建一个基础的在线聊天系统。以下将详细阐述Socket编程的基本概念,以及如何利用它来创建聊天室。 首先,Socket是基于TCP/IP协议族的一种通信接口,...

    用swing和socket实现的聊天室

    总结起来,"用swing和socket实现的聊天室"项目涵盖了Java GUI编程、网络编程以及数据库操作等多个核心概念。通过这个项目,开发者可以锻炼到客户端-服务器架构的实现,理解Socket通信的原理,以及如何利用数据库存储...

    Socket实现简单聊天室功能

    在这个"Socket实现简单聊天室功能"的例子中,我们将会深入理解如何利用Socket来创建一个基本的聊天应用,使两台或多台电脑能够进行实时交互。 首先,我们需要了解Socket的基本概念。Socket可以被看作是网络上的端点...

    Socket实现简易聊天室源码

    在这个"Socket实现简易聊天室源码"中,我们可以深入理解Socket如何在客户端和服务器之间建立连接,进行数据传输,从而构建一个简单的聊天室系统。 首先,我们来看一下Socket的基本概念。Socket,也被称为套接字,是...

    socket 实现多人聊天

    总的来说,实现“socket多人聊天”涉及到的知识点包括TCP/IP协议基础、Socket编程、线程处理、数据传输以及错误处理等。通过理解和掌握这些技术,我们可以构建出一个高效、可靠的多人聊天系统。在提供的压缩包文件中...

    基于socket.io聊天室功能

    在这个“基于socket.io聊天室功能”的项目中,我们将探讨如何使用 Socket.IO 构建一个简单的聊天室应用。 1. **Socket.IO 的基本概念** - **事件驱动**:Socket.IO 的通信基于事件模型,客户端和服务器通过发送和...

    linux 下的shell socket实现聊天室

    当我们谈论“Linux下的Shell socket实现聊天室”时,我们实际上是在讨论如何利用Shell脚本结合socket编程来创建一个基本的网络通信环境,使得多用户可以通过网络进行实时的文本交流。这个聊天室应用通常包括两个主要...

    C++用win socket api实现的简单的聊天室程序

    本程序用winsocket 实现了一个基于c/s 架构的简单的聊天室程序。 采用面向连结的socket api, 信息发送、接收为阻塞同步方式。为实现多用户聊天,采用了服务器端分发线程处理,主线程阻塞接受客户端socket, 每接收...

    socket实现简单聊天室功能 服务端和客户端代码

    本篇将深入探讨如何使用Socket实现一个简单的聊天室功能,包括服务端和客户端的代码实现。 一、Socket基础 Socket是网络通信的基本单元,它提供了进程间通信(IPC)的能力,尤其是跨越网络的进程间通信。在TCP/IP...

    C# WinForm使用Socket通信搭建简易聊天室

    在本文中,我们将深入探讨如何使用C# WinForm和Socket通信技术来搭建一个简单的聊天室。Socket编程是网络通信的基础,而C# WinForm则提供了一个用户友好的图形界面,两者结合可以创建出功能丰富的交互式应用。 首先...

    Socket实现的聊天室

    Socket实现的聊天室是一种基于网络通信的多用户交互平台,主要利用了Socket编程技术来构建。Socket在计算机网络中扮演着客户端与服务器间通信的重要角色,它为应用程序提供了低级别的、面向连接的、可靠的字节流网络...

    C#Socket 多线程聊天室A

    在C#编程环境中,Socket和多线程技术的结合被广泛应用于网络通信,尤其是在构建聊天室这类实时交互的应用中。本项目"**C#Socket 多线程聊天室A**"是一个很好的学习资源,它展示了如何利用C#的Socket类进行网络通信...

    java的Socket实现的多人聊天程序

    Java的Socket实现的多人聊天程序是一个基于网络通信的项目,主要利用了Java的Socket类来构建客户端和服务端的通信桥梁。Socket是TCP/IP协议的一部分,它提供了两台计算机之间进行数据传输的基础。在这个项目中,...

    C#多线程与Socket聊天室的实现

    本文将深入探讨如何使用C#语言实现一个基于TCP/IP协议的多线程Socket聊天室。这个聊天室功能允许局域网内的多台计算机进行实时信息交互,虽然没有在广域网环境下测试,但在局域网内能有效工作。 首先,我们要理解...

    Socket_聊天室_

    Socket编程是网络通信的核心技术,尤其在开发多人在线聊天室这样的应用中,它的重要性不言而喻。Socket,又称套接字,是操作系统提供的一种进程间通信机制,它允许两个或多个应用程序通过网络进行数据交换。在这个...

    用SOCKET实现简单的聊天室程序

    本文将深入探讨如何使用Socket来构建一个简单的聊天室程序。首先,我们理解Socket的概念:它是一种在网络之间建立连接并进行数据交换的机制,是应用层与传输层之间的接口。 在我们的示例中,"Client"和"Server"是两...

    Python实现的多人聊天室源码,基于socket tcp通信,使用tkinter做客户端界面,含可执行文件

    在本项目中,我们探讨的是一个使用Python编程语言实现的多人聊天室,它基于socket TCP通信协议,并且利用Tkinter库构建了用户友好的客户端界面。这个聊天室系统允许多个用户同时在线交流,增强了实时互动性。以下是...

    Socket +WinForm聊天室(经典)

    【Socket + WinForm聊天室(经典)】 在IT领域,Socket编程是网络通信的基础,而WinForm则是.NET Framework中用于创建桌面应用的框架。本文将深入探讨如何利用Socket技术和WinForm构建一个经典的聊天室应用程序。 ...

    用Java socket 实现网络聊天室设计完美的参考资料

    ### 用Java Socket 实现网络聊天室设计完美参考资料 #### 一、Socket简介及Java Socket支持 **Socket** 是一种用于网络通信编程的基础组件,它允许不同计算机之间通过TCP/IP协议进行数据交换。在计算机科学中,...

    Socket实现聊天室功能

    在这个案例中,我们将讨论如何使用Socket来实现一个简单的聊天室功能,包括服务器端和客户端的实现。 首先,我们要理解Socket的基本概念。Socket是网络通信中的一个抽象接口,可以看作是两台计算机之间的通信通道。...

Global site tag (gtag.js) - Google Analytics