方枪枪的java世界

不要因为风雨飘落就停止了你的脚步,真正的得失就在你的心中。 做喜欢做的事,不轻言放弃!

ChatServer

package com.tianhe.frm.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Scanner;

/**
 *
 *<br>
 * 服务器的实现效果: <br>
 *<br>
 * 1.输入-help得到所有有关服务器操作的命令 <br>
 *<br>
 * 2.输入-run进入服务器各项内容初始化 <br>
 *<br>
 * 3.输入-stop断开服务器 <br>
 *<br>
 * 4.输入-quit断开服务器,并退出操作 <br>
 *<br>
 * 5.服务器创建成功后,会通过单独的线程运行监听客户端信息(listenLink) <br>
 *<br>
 * 6.服务器接收到数据后,会将数据移交至数据分析器(analyseMes)处理 <br>
 *<br>
 * 7.当用户确定连接并确定昵称后,服务器将该用户的地址及姓名存储在infoMemory中。 <br>
 *<br>
 *<br>
 *<br>
 *<br>
 * 服务器的类与方法: <br>
 *<br>
 * 1.测试服务器创建:testServer(String ip,int serverPort) <br>
 *<br>
 * 2.初始化服务器 :initServer(String ip,int serverPort) <br>
 *<br>
 * 3.确定IP与Port :fixServerLink(String ip,int serverPort) <br>
 *<br>
 * 4.信息监听器 :listenLink() <br>
 *<br>
 * 5.数据分析器 :analyseMes(String mes) <br>
 *<br>
 * 6.获取地址用户名:getConsumerName(SocketAddress sa) <br>
 *<br>
 * 7.数据转发器 :transforMes(String mes) <br>
 *<br>
 * 8.数据单项转发器:transforMesSingle(SocketAddress adr,String mes) <br>
 *<br>
 * 9.停止服务器 :cutServer() <br>
 *<br>
 * 10.获得帮助列表 :helpList() <br>
 *<br>
 * 11.错误提示方法 :errorTip(String str) <br>
 *<br>
 * 12.在主函数中进行相应操作 <br>
 *<br>
 *<br>
 * 重点注意的地方: <br>
 *<br>
 * 与客户端相仿,为了顺利监听信息,需要另一个线程运行信息监听器
 *
 */
public class ChatServer implements Runnable
{
    private DatagramSocket ds = null;
   
    private DatagramPacket dp = null;
   
    private String serverIp = "localhost";
   
    private int serverPort = 9999;
   
    private InetAddress serverAddr = null;
   
   
    // 开始运行监听的变量
    private boolean beStart = false;
   
    // 信息存储器
    private Hashtable<String, SocketAddress> userCache = new Hashtable<String, SocketAddress>();
   
    /**
     * 服务器初始化
     *
     * @param ip
     * @param serverPort
     */
    public boolean initServer(InetAddress serverAddr, int serverPort)
    {
        this.serverAddr = serverAddr;
        this.serverPort = serverPort;
       
        try
        {
            ds = new DatagramSocket(serverPort, serverAddr);
            System.out.println("!-The Server Initialization Success!");
            // 可以开始运行变量
            beStart = true;
        }
        catch (SocketException s)
        {
            // 如果出现异常,则服务器测试不通过
            errorTip("!-The Server Initialization Fail!--new DatagramSocket(" + serverPort + ", " + serverAddr + ")");
            return false;
        }
       
        return true;
    }
   
    /**
     * 监听信息
     *
     */
    public void listenLink()
    {
        byte[] buf = new byte[1024];
        String mes = null;
        try
        {
            dp = new DatagramPacket(buf, buf.length);
            System.out.println("!-The Server starts listenning to message.");
            while (beStart)
            {
                ds.receive(dp);
                mes = new String(buf, 0, dp.getLength());
                // 将获取的数据传递至数据分析器
                this.analyseMes(mes);
            }
        }
        catch (IOException e)
        {
            errorTip("!-The Server Can not receive message");
        }
    }
   
    /**
     * 数据分析器,给予相应处理
     *
     * @param mes
     */
    private void analyseMes(String mes)
    {
        // 获取当前客户端的地址:
        SocketAddress adr = dp.getSocketAddress();
       
        // -test:进行服务器与客户端的连接测试
        // 若成功,则将该客户端发送成功消息
        if (mes.trim().equalsIgnoreCase("-test"))
        {
            transforMesSingle(adr, "-test: !-From Server:Succeed in Testing.");
        }
       
        // -quit:接受客户端退出信息
        // 将该用户的退出信息转发至所有在线成员
        else if (mes.trim().equalsIgnoreCase("-quit"))
        {
            String name = this.getConsumerName(adr);
            System.out.println(name + "//" + adr + " quit! ");
            transforMes("* " + name + "退出聊天室");
            userCache.remove(name);
        }
       
        // -getList:接受客户端获取列表的请求
        // 将所有用户连接为字符串的形式,如:"-getList,用户1,用户2...用户n"
        else if (mes.trim().equals("-getList"))
        {
            StringBuffer list = new StringBuffer();
            list.append("-getList,");
            Enumeration<String> names = userCache.keys();
            while (names.hasMoreElements())
            {
                list.append(names.nextElement() + ",");
            }
            transforMesSingle(dp.getSocketAddress(), list.toString());
        }
       
        // -to:接受客户端请求,将信息转发给相应客户
        // 如果目标客户不存在,则向请求客户发送相应消息
        else if (mes.indexOf("-to ") != -1 && mes.startsWith("-to "))
        {
            String main = mes.substring("-to ".length(), mes.length());
            String toName = main.substring(0, main.indexOf(" "));
            String name = this.getConsumerName(adr);
            String con = name + " say to you :" + main.substring(toName.length() + 1, main.length());
            if (!userCache.containsKey(toName))
                transforMesSingle(adr, "!-The message can not be recevie by whom you send for,please check out.");
            else
                transforMesSingle(userCache.get(toName), con);
        }
       
        // -nick:接受客户端登录请求
        // 如果输入的匿名不存在,则登记该用户与infoMemory
        // 如果存在则返回相应提示
        else if (mes.indexOf("-nick ") != -1 && mes.startsWith("-nick "))
        {
            String nickName = mes.substring("-nick ".length(), mes.length());
            if (userCache.containsKey(nickName))
                transforMesSingle(adr, "-nick: !-The nickname you post is already exist,please try others.");
            else
            {
                userCache.put(nickName, adr);
                transforMes("Welcome " + nickName + " to Sunspot Chat!");
                System.out.println(nickName + "//" + adr.toString() + " succeed in lanuching.");
            }
        }
       
        // 一般消息将会转发至所有用户
        else
        {
            String name = this.getConsumerName(adr);
            transforMes(name + ": " + mes);
        }
    }
   
    /**
     * 通过地址得到用户的昵称 由于Hashtable无法通过Value获取Key,所有专门写该方法
     *
     * @param sa
     * @return
     */
    private String getConsumerName(SocketAddress sa)
    {
        Enumeration<String> names = userCache.keys();
        String name = null;
        while (names.hasMoreElements())
        {
            String temp = names.nextElement();
            SocketAddress adrs = userCache.get(temp);
            // 进行比较
            if (sa.equals(adrs))
            {
                name = temp;
                break;
            }
        }
        return name;
    }
   
    /**
     * 向所有的用户发送数据
     *
     * @param mes
     */
    public void transforMes(String mes)
    {
        byte[] buf = mes.getBytes();
        DatagramPacket sendDatas = null;
        Enumeration<SocketAddress> all = userCache.elements();
        try
        {
            while (all.hasMoreElements())
            {
                sendDatas = new DatagramPacket(buf, buf.length, all.nextElement());
                ds.send(sendDatas);
            }
        }
        catch (SocketException s)
        {
            errorTip("!-The feedback address is error!");
        }
        catch (IOException i)
        {
            errorTip("!-Can not send message!");
        }
    }
   
    /**
     * 向单个用户发送数据
     *
     * @param adr
     * @param mes
     */
    public void transforMesSingle(SocketAddress adr, String mes)
    {
        byte[] buf = mes.getBytes();
        try
        {
            DatagramPacket sendDatas = new DatagramPacket(buf, buf.length, adr);
            ds.send(sendDatas);
        }
        catch (SocketException s)
        {
            errorTip("!-The feedback address is error!");
        }
        catch (IOException i)
        {
            errorTip("!-Can not send message!");
        }
    }
   
    /**
     * 断开连接
     *
     */
    public void cutServer()
    {
        beStart = false;
        if (ds != null)
            ds.close();
        System.out.println("!-The ds is done.");
    }
   
    public void helpList()
    {
        System.out.println("-help" + "    获取服务器相应操作的帮助" + "\n" + "-run " + "    运行服务器,并同时建立信息监听" + "\n" + "-stop"
                + "    停止服务器" + "\n" + "-quit" + "    停止服务器,并退出命令" + "\n");
    }
   
    /**
     * 线程
     */
    public void run()
    {
        listenLink();
    }
   
    /**
     * 主要操作
     *
     * @param args
     */
    public static void main(String[] args)
    {
        ChatServer cs = new ChatServer();
       
        // serverAddr && serverPort
        String serverIp = "localhost";
        int serverPort = 9999;
        InetAddress serverAddr = null;
       
        if (args != null && args.length > 0)
        {
            int i = 0;
            while (i < args.length)
            {
                // serverAddr
                if (args[i].equalsIgnoreCase("-ServerAddr"))
                {
                    i = i + 1;
                    serverIp = args[i];
                    continue;
                }
               
                // serverPort
                int ti = 9999;
                if (args[i].equalsIgnoreCase("-ServerPort"))
                {
                    i = i + 1;
                    ti = Integer.parseInt(args[i]);
                    if (ti > 0)
                    {
                        serverPort = ti;
                    }
                    i = i + 1;
                    continue;
                }
            }
        }
       
        try
        {
            serverAddr = InetAddress.getByName(serverIp);
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
            System.exit(-1);
        }
       
        // 建立输入
        System.out.println("Lexiaofei聊天室创建成功!");
        Scanner input = new Scanner(System.in);
        System.out.println("!-请输入服务端命令:");
       
        // 开始输入
        String command = null;
        // 如果输入quit将断开连接,并退出操作
        while (!(command = input.next()).equalsIgnoreCase("-quit"))
        {
            // 获取帮助
            if (command.equalsIgnoreCase("-help"))
            {
                cs.helpList();
            }
           
            // 初始化服务器
            if (command.equalsIgnoreCase("-run"))
            {
                boolean goon = true;
                while (goon)
                {
                   
                    // 测试服务器创建,如果成功则同时为信息监听器建立线程
                    System.out.println("!-创建服务器并运行...");
                    if (cs.initServer(serverAddr, serverPort))
                    {
                        new Thread(cs).start();
                        goon = false;
                    }
                    else
                        System.out.println("!-服务器创建失败,请检查!");
                }
            }
           
            // 关闭服务器
            if (command.equalsIgnoreCase("-stop"))
            {
                cs.cutServer();
            }
        }
        input.close();
        cs.cutServer();
    }
   
    /**
     * 错误提示
     *
     * @param str
     */
    public static void errorTip(String str)
    {
        System.out.println("-----------------\n" + str + "\n-----------------");
    }
}

posted on 2013-12-16 21:12 做强大的自己 阅读(191) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: