• 使用 ServerSocket 建立聊天服务器-2


    1.

    从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新建一个类,将这些新建的线程管理起来,然后实现他们之间的相互通信.(类似于微信加群聊天的功能)

    由于一个聊天服务器只有一个管理者,所以创建chatManager.java管理类,需要对类做单例化的处理

     ===================================================================

    1.项目截图

     2.ChatManager.java

    package com.nantian.socket;

    import java.util.Vector;

    public class ChatManager {
    /**
    * 由于一个聊天服务器只有一个管理者,所以创建chatManager.java管理类,需要对类做单例化的处理
    */
    //单例化第一步,需要构造private的构造方法
    private ChatManager() {}
    //为当前类创建实例
    private static final ChatManager cm=new ChatManager();
    public static ChatManager getChatManager() {
    return cm;
    }
    //===========以上代码完成了单例化的操作

    Vector<ChatSocket> vector=new Vector<ChatSocket>();
    //为当前类添加一个新的chatSocket
    public void add(ChatSocket cs) {
    vector.add(cs);
    }
    //还需实现一个方法,实现其中一个线程调用下面的方法向其他客户端发送信息
    //ChatSocket cs(当前线程),String out(发送的信息)
    public void publish(ChatSocket cs,String out) {
    //发送给所有线程,需要对集合中的线程进行遍历
    for (int i = 0; i < vector.size(); i++) {
    //获取循环中的第i个对象
    ChatSocket csChatSocket=vector.get(i);
    //当前发送的线程没必要接收这条信息
    //如果等于当前发送对象的话,就不执行发送消息
    if (!cs.equals(csChatSocket)) {
    //调用out()方法将字符串out传输出去
    csChatSocket.Out(out);
    }
    }
    }

    }

    ===================================================================

    2.ChatSocket.java

    package com.nantian.socket;

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

    public class ChatSocket extends Thread{
    //本地需要有一个socket对象,来接入传入的值
    Socket socket;
    /**
    * 创建构造方法
    */
    public ChatSocket(Socket s) {
    this.socket=s;
    }
    /**
    * 运行MyServerSocket类后,没有值输出后所写的方法
    * @param out
    */
    public void Out(String out) {
    try {
    socket.getOutputStream().write(out.getBytes("UTF-8"));
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    /**
    * 复写run方法,执行后台的功能
    */
    @Override
    public void run() {
    //将socket的输入流进行包装
    try {
    BufferedReader br=
    new BufferedReader(
    new InputStreamReader(
    socket.getInputStream(),"UTF-8"));
    //创建本地对象
    String line=null;
    while ((line=br.readLine())!=null) {
    //聊天室中的所有信息发送给所有人,需要调用publish()方法
    //将自己传入使用this
    ChatManager.getChatManager().publish(this, line);
    }
    //while循环结束,需要将当前的流关闭
    br.close();
    } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }

    ===================================================================

    3.MyServerSocket.java

    package com.nantian.socket;
    //ctrl+shift+o删除多余的jar包
    public class MyServerSocket {

    public static void main(String[] args) {
    new ServerListener().start();
    }
    }

    ===================================================================

    4.ServerListener.java

    package com.nantian.socket;

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;

    import javax.swing.JOptionPane;

    public class ServerListener extends Thread{

    @Override
    public void run() {
    try {
    //port取值范围:1-65535(通常取值较大,这样可以和系统的分开)
    ServerSocket serverSocket=new ServerSocket(12345);
    //循环监听来自客户端的连接
    while(true) {
    //监听客户端的连接
    //accept()为一个阻塞的方法,会阻塞当前的线程
    //ServerSocket的accept()方法是侦听并接受到此套接字的连接,
    //就是一直等待连接,此方法在连接传入之前一直阻塞。直到接受到有socket的连接。
    //故创建ServerLIstener extends Thread
    Socket socket=serverSocket.accept();
    //建立连接
    JOptionPane.showMessageDialog(null, "有客户端连接到了本机的12345端口");
    //因为每一个Socket要与客户端独立的通信,所以socket需要另起一个线程
    //将socket传递给新的线程,用于socket通信,故创建ChatSocket extends Thread
    ChatSocket cs=new ChatSocket(socket);
    cs.start();
    //将cs添加到聊天管理器中
    ChatManager.getChatManager().add(cs);
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    }

    ===================================================================

    5.run as -->java application 

    cmd,输入telnet localhost 12345,截图如下

     

  • 相关阅读:
    Android 操作系统的内存回收机制(转载)
    如何减少代码中的分支语句
    Android中动画学习
    Android中 AsyncTask
    Linux安装后更新系统
    看百度宣传片
    可爱的linux mint 11
    ubuntu 修改root密码
    SHA256加密算法封装[我的代码库]
    使用maven,svn和CruiseControl做持续集成
  • 原文地址:https://www.cnblogs.com/curedfisher/p/11936915.html
Copyright © 2020-2023  润新知