`
kree
  • 浏览: 128838 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java非阻塞聊天室源码 Client

阅读更多
//client
public class NBChatClient {
    private static final String CMD_QUIT = "/quit";
    
    private Selector sel;
    private SocketChannel socket;
    private boolean feedback = false;
    private boolean loginSeccess = false;
    private boolean active = true;
    
    private Object oLogin = new Object();
    private ByteBuffer buf = ByteBuffer.allocate(128);
    private static Properties props = new Properties();
    NBChatClient(String fName) {
        initConfig(fName);
        initClient();
        start();
    }
    
    private static void initConfig(String fName) {
        try {
            InputStream in = NBChatServer.class.getClassLoader().getResourceAsStream(fName);
            props.load(in);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
    
    private void initClient() {
        String ipStr = props.getProperty(NBChatServer.key_ip);
        String portStr = props.getProperty(NBChatServer.key_port);
        
        try {
            sel = Selector.open();
            this.socket = SocketChannel.open();
            InetAddress ip = InetAddress.getByName(ipStr);
            InetSocketAddress remote = new InetSocketAddress(ip, Integer.parseInt(portStr));
            this.socket.connect(remote);
            this.socket.configureBlocking(NBChatServer.NON_BLOCKING);
            socket.register(sel, SelectionKey.OP_READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }    
    private void start() {
        //create a new thread to read message from server.
        new Thread() {
            public void run() {
               
                int readyCount = 0;
                while (active) {
                    try {
                        readyCount = sel.select();
                    } catch (IOException e) {
                        if (sel.isOpen())
                            continue;
                        else
                            e.printStackTrace();
                    }
                    if (readyCount == 0)
                        continue;
                    Set readyKeys = sel.selectedKeys();
                    Iterator keys = readyKeys.iterator();
                    while (keys.hasNext()) {
                        SelectionKey key = (SelectionKey) keys.next();
                        if (!key.isValid())
                            continue;
                        keys.remove();
                        try {
                            if (key.isReadable()) {
                                SocketChannel socket = (SocketChannel) key.channel();
                                buf.clear();
                                socket.read(buf);
                                String input = ChatUtil.decode(buf);
                                
                                //如果已经授权,则直接输出信息。
                                if (loginSeccess) {
                                    System.out.println(input);
                                } 
                                //如果没有登录, 且返回信息为授权登录, 则将登录旗标置为true, 并notify主线程。
                                else if (NBChatServer.LOGIN_OK.equals(input)) {
                                    System.out.println("-------------------------------------------- Welcome ------------------------------------ ");
                                    System.out.println("---------------------------------Non Blocking Chat Program------------------------------- ");
                                    System.out.println("----------------------------------------Author: ChenLinping ----------------------------- ");
                                    System.out.println("------------------------------------------------------------------------------------------");
                                    feedback = loginSeccess = true;
                                    
                                    
//                                    //用sleep保证此线程的notify在main线程的wait之后.
//                                    //如果没有这个sleep,则可能发生先notify再wait的情况,则mail线程将一直等待oLogin的锁而阻塞。
//                                    try {
//                                        Thread.sleep(100);
//                                    } catch (InterruptedException e) {
//                                        e.printStackTrace();
//                                    }
                                    
                                    synchronized (oLogin) {
                                        oLogin.notifyAll();
                                    }
                                } 
                                //否则输出permission denied信息。
                                else {
                                    System.out.println("Permission denied~");
                                    feedback = true;
//                                    try {
//                                        Thread.sleep(100);
//                                    } catch (InterruptedException e) {
//                                        e.printStackTrace();
//                                    }
                                    
                                    synchronized (oLogin) {
                                        oLogin.notifyAll();
                                    }
                                }
                            }
                        } catch (IOException e) {
                            System.out.println("You have disconnected!");
                            key.cancel();
                            try {
                                key.channel().close();
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                        }
                    }
                }
            }
        }.start();
    }
    private void handleMsg(String s) throws IOException {
        if (CMD_QUIT.equals(s)) {
            this.active = false;
            socket.close();
            System.exit(-1);
        } else
        socket.write(ByteBuffer.wrap(s.getBytes()));
    }
    private void doLogin(NBChatClient client, BufferedReader input) throws IOException {
        while (!client.loginSeccess) {
            System.out.print("user:");
            String user = input.readLine();
            System.out.print("pass:");
            String pass = input.readLine();
            
            client.handleMsg("/login:"+user+"/"+pass);
            
            //可能存在的一种情况是:程序运行到这里,mail线程还没有block,而server已经响应了,告知client登录成功或失败。这种情况下,则不需要block mail线程。
            //如果是登录成功,则不需要block线程,而应该直接进入聊天。
            //如果是登录失败,也不需要block线程,而应该直接让用户重新登录。
            while (!client.feedback) {
                //输入登录信息后,阻塞main线程,等待系统验证,如果验证成功,则可以开始聊天。
                synchronized (client.oLogin) {
                    try {
                        client.oLogin.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        NBChatClient client = new NBChatClient(args[0]);
        try {
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            
            client.doLogin(client, input);
            
            String s;
            while ((s = input.readLine()) != null)
                client.handleMsg(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} 

 

分享到:
评论

相关推荐

    Java课程设计Java Socket实现聊天室源码内含项目说明.zip

    Java课程设计Java Socket实现聊天室源码内含项目说明.zipJava课程设计Java Socket实现聊天室源码内含项目说明.zipJava课程设计Java Socket实现聊天室源码内含项目说明.zipJava课程设计Java Socket实现聊天室源码内含...

    java完整聊天室系统(源码)

    java完整聊天室系统(源码) java完整聊天室系统(源码)

    多人聊天室源码.rar

    【标题】:“多人聊天室源码.rar”是一个包含Java编程语言实现的多人在线聊天室的源代码压缩包。这个项目可能是一个实时通信系统的实例,旨在教授如何构建一个基本的网络聊天平台,允许用户进行实时交流。 【描述】...

    基于Java的P2P多用户在线聊天室项目源码

    综上所述,基于Java的P2P多用户在线聊天室项目源码涵盖了许多高级Java技术,包括P2P网络编程、数据库操作、GUI设计、实时通信、安全性和文件共享。对于想深入学习Java网络编程和分布式系统的人来说,这是一个非常有...

    java的tcp协议小聊天室源码

    在本项目"java的tcp协议小聊天室源码"中,我们将探讨如何使用Java实现一个简单的TCP聊天室。这个聊天室功能虽简单,但足以帮助初学者理解TCP通信的基本原理和Java网络编程的实践。 首先,TCP(Transmission Control...

    聊天室源码 JAVA 即时通讯

    【标题】"聊天室源码 JAVA 即时通讯"揭示了这个项目的核心是使用Java语言构建的一个实时通信系统,特别适合于在线聊天环境。在IT领域,即时通讯(Instant Messaging,简称IM)系统是用于实现实时、双向、低延迟通信...

    java聊天室源码,java聊天室下载

    Java聊天室源码是学习和理解网络编程及多线程技术的理想实践项目。在这个项目中,我们主要关注两个核心文件:`TestServer.java`和`TestClient.java`,它们分别代表了聊天室的服务器端和客户端。 首先,让我们深入...

    Java聊天室课程设计源码和文档附SQLServer数据库.rar

    附SQLServer数据库的Java聊天室课程设计源码和文档,源代码完整,学习网络编程很不错的参考程序。界面像网页版 的聊天室,可对所有人发消息,聊天室的功能都基本具备了。源代码文件包括了:聊天系统登录程序、聊天...

    JAVA局域网聊天室源码

    【JAVA局域网聊天室源码】是一个基于Java编程语言实现的本地网络通信项目,它允许在同一局域网内的用户通过简单的客户端-服务器架构进行实时的文本聊天。这个项目主要包含两个核心部分:ChatServer(服务器端)和...

    Java课设-简单聊天室的实现源码.zip

    Java课设-简单聊天室的实现源码.zipJava课设-简单聊天室的实现源码.zipJava课设-简单聊天室的实现源码.zipJava课设-简单聊天室的实现源码.zipJava课设-简单聊天室的实现源码.zipJava课设-简单聊天室的实现源码.zip...

    UI多人聊天室Java源码

    本资源提供的是一个基于Java实现的简单可视化多人聊天室源码。这个项目旨在帮助学习者理解和实践网络编程、多线程以及用户界面设计等核心Java技术。以下将详细阐述其中涉及的知识点: 1. **Java Socket编程**:聊天...

    Java课程设计全套源码:聊天室源码 数据库.rar

    Java课程设计全套源码:聊天室源码 SQL2000数据库,主程序分为服务端和客户端,界面友好,可实现的功能模块:用户注册、资料保存、多用户登录、多用户同聊、私聊、保存用户记录、用户离开记录自动清除、在线人数监视...

    java socket 聊天室源码.zip

    java socket 聊天室源码java socket 聊天室源码java socket 聊天室源码java socket 聊天室源码java socket 聊天室源码java socket 聊天室源码

    JAVA源码java聊天室JAVA源码java聊天室

    JAVA源码java聊天室JAVA源码java聊天室

    Java swing聊天室源码

    Java swing聊天室源码 1、、实现要求 能够完成多线程的用户聊天程序。 2、实现技术 a)使用ServerSocket、Socket完成服务端和客户端的连接。 b)服务端使用多线程的方式可以接受多个客户端。 c)使用对象的方式,在...

    java实现的非阻塞Http服务器文档和源码

    在提供的"Java实现非阻塞的HTTP服务器2008"源码中,你可以看到具体的实现细节,例如如何配置和使用Selector,如何处理HTTP请求和响应,以及如何进行错误处理和资源管理。分析和理解这段源码,对于理解Java NIO和非...

    java nio 聊天室源码

    在这个“java nio 聊天室源码”项目中,开发者使用了NIO来构建一个聊天室应用,以实现用户之间的实时通信。 1. **Java NIO基础** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的,如SocketChannel、...

    java-web聊天室源码

    【Java-Web聊天室源码解析】 在互联网应用开发中,聊天室系统是常见的社交功能之一,它允许用户实时互动交流。本项目“java-web-html5-php”提供了一个基于Java Web、HTML5和PHP的聊天室源码,帮助开发者理解和构建...

    Java实验室管理系统源码.zip

    Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验室管理系统源码 Java实验...

    java 界面聊天室源码.rar

    Java界面聊天室源码是一个基于Java编程语言实现的图形用户界面(GUI)应用程序,用于创建一个简单的聊天室环境。这个项目通常会包含多个文件和类,用于处理用户交互、网络通信以及界面展示等功能。让我们详细了解...

Global site tag (gtag.js) - Google Analytics