DJ(Delphi/JAVA)_fans的专栏

珍惜眼前、抓住机会、奋力拼搏、营造未来

JAVA NIO

import java.net.ServerSocket;
import java.net.InetSocketAddress;
import java.net.Socket;

import java.util.*;
import java.io.IOException;

import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.Channel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.*;
import java.nio.CharBuffer;

import com.guanda.qqserver.util.CommandDefine;
import com.guanda.qqserver.bussiness.*;
import com.guanda.qqserver.util.Functions;
import com.guanda.qqserver.protocol.OnLineClientInfo;
import com.guanda.qqserver.util.OnLineList;

public class QQServer implements Runnable
{
  private static int port;

//  private final ByteBuffer buffer = ByteBuffer.allocate(16348);
  /**
   * 构造函数
   * @param port  服务器的监听端口
   */
  public QQServer()
  {
    port = Integer.parseInt(Functions.getProperties("tcpserver.prot"));
    new Thread(this).start();
  }

  public void run()
  {
    try
    {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking( false );
      ServerSocket ss = ssc.socket();
      InetSocketAddress isa = new InetSocketAddress(Functions.getProperties("tcpserver.ip"),port);
      ss.bind(isa);
      Selector selector = Selector.open();
      ssc.register( selector, SelectionKey.OP_ACCEPT );
      System.out.println( "Listening on port "+port );
      while (true)
      {
        int num = selector.select();
//        System.out.println("Return Set Size: "+num);
        if (num == 0)
          continue;
        Set keys = selector.selectedKeys();

        Iterator it = keys.iterator();
        while (it.hasNext())
        {
          SelectionKey key = (SelectionKey)it.next();
          it.remove();
          if(key.isAcceptable())
          {
            //System.out.println( "accept-----" );
            Socket s = ss.accept();
            Functions.writeLog("Got connection from "+s );
            SocketChannel sc = s.getChannel();
            sc.configureBlocking(false);
            sc.register(selector,SelectionKey.OP_READ);
          }
          else if(key.isReadable())
          {
           // System.out.println("Read-----");
            SocketChannel sc = null;
            try
            {
              sc = (SocketChannel)key.channel();
              boolean ok = ProcessInput( sc );
              if(!ok)
              {
                new ChangeUserStateBuss(sc).sendOffLineMessage();
                OnLineList.removeUserFromList(sc);
                key.cancel();
                Socket s = null;
                try
                {
                  s = sc.socket();
                  s.close();
                }
                catch( IOException ie )
                {
                  Functions.writeLog(ie);
                  System.err.println("Error closing socket ");
                }
              }
            }
            catch(IOException ie)
            {
              key.cancel();
              try
              {
                sc.close();
                new ChangeUserStateBuss(sc).sendOffLineMessage();
                OnLineList.removeUserFromList(sc);
              }
              catch(IOException ie2)
              {
                Functions.writeLog(ie2);
                System.out.println( ie2 );
              }
              System.out.println( "Closed channnel:"+sc );
            }
          }
        }
      System.out.println("");
  //keys.clear();
      }
    }
    catch(IOException ie)
    {
      Functions.writeLog(ie);
      System.err.println( ie );
    }
 catch(java.nio.channels.CancelledKeyException ce)
 {
   Functions.writeLog(ce);
   System.err.println(ce);
 }
 catch(Exception ee)
 {
   Functions.writeLog("unKowned Exception !");
   System.err.println(ee);
   Functions.writeLog(ee);
 }
  }
  /**
   * 处理指定通道的输入流
   * @param 需要处理的Socket通道
   * @return true:读取到数据    false:收到客户端断开的消息
   */
  private boolean ProcessInput(SocketChannel sc) throws IOException
  {
    CharBuffer cb;
    ///包头:Command_ID
    String command_ID ="";
    ByteBuffer headpacket = ByteBuffer.allocate(8);
    sc.read(headpacket);
    headpacket.flip();
    if (headpacket.limit() == 0)
      return false;
    command_ID =  Functions.ChangeByteToString(headpacket);
    if (command_ID.equals(CommandDefine.GUANDA_CONNECT_CHECKED))
    {
      System.out.println("链路检测-------");
      return true; //链路检测
    }
    System.out.println("Command_ID = "+command_ID);
    //包头:数据包大小
    ///在此处加入消息头判断对无效消息格式中断处理
    int packetSize = this.GetPacketSize(sc);
    if (packetSize == -1)
        return false;
    System.out.println("Parcket_SIZE:"+packetSize);
    //包体
    ByteBuffer temp3 = ByteBuffer.allocate(packetSize);
    sc.read(temp3);
    temp3.flip();
    if (temp3.limit() == 0)
      return false;
    cb = Functions.ChangeByteToChar(temp3);
    if (cb != null)
    {
      System.out.print("cb:");
      PrintCharBufferInfo(cb);
      System.out.println("Packet_Content:" + cb.toString());
      //////根据COMMAND_ID选择对应的处理方法,然后将处理结果回显到客户端。
      StringBuffer packetBuffer = new StringBuffer();
      packetBuffer.append("Command_ID=").append(command_ID).append("/r/n");
      packetBuffer.append("BodySize=").append(packetSize).append("/r/n");
      packetBuffer.append("BodyContent=").append(cb.toString()).append("/r/n");
      Functions.writeLog(packetBuffer.toString());
      if (command_ID.equals(CommandDefine.GUANDA_USER_AUTH))
      {
        //客户端发送的登陆验证消息
        new UserLoginBuss(sc,cb.toString()).login();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_MESSAGE_SEND))
      {
        //客户端发送的文字信息交流消息
        new TalkBuss(sc,cb.toString()).transferMessage();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_BROADCAST_SEND))
      {
        //客户端发送过来的发送发送系统公告消息
        new BroadCastBuss(sc,cb.toString()).transferMessage();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_DEPTBROADCAST_SEND))
      {
        //客户端发送过来的发送部门公告消息
        new DeptBroadCastBuss(sc,cb.toString()).transferMessage();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SET_USERINFO))
      {
        //客户端发送过来的饿个人设置消息
        new UserInfoBuss(sc,cb.toString()).userInfoSet();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_ONLINEUSERS))
      {
        //客户端发送过来的获取在线用户列表的消息
        new UserInfoBuss(sc,cb.toString()).getOnLineUserList();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_OPERATOR))
      {
        //客户端发送过来的权限验证消息
        new UserOperatorBuss(sc,cb.toString()).CheckUserOperator();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_OFFLINEMESSAGE))
      {
        //客户端发送过来的获取离线消息
        new OffLineMessageSendBuss(sc,cb.toString()).chooseTranactProcess();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_CHANGESTATE_SEND))
      {
        //客户端发送过来的状态切换消息
        new ChangeUserStateBuss(sc,cb.toString()).changeUserState();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_MESSAGE_SYSTEM))
      {
        //应用系统推送过来的系统消息
        new SystemMessageBuss(sc,cb.toString()).transferMessage();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SYSTEM_CHANGED))
      {
        //应用系统推送过来的人事变动消息
        new PCMessageBuss(sc,cb.toString()).transferMessage();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_ALLIMAGEINDEX))
      {
        //得到全部用户的头象编号
        new UserInfoBuss(sc,cb.toString()).getAllImageIndex();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_USERINFO))
      {
        //得到指定用户的详细信息
        new UserInfoBuss(sc,cb.toString()).getUserInfobyID();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_GET_USEROPERATOR))
      {
        //系统维护人员读取指定用户的操作权限
        new UserOperatorBuss(sc,cb.toString()).sysManReadUserOperators();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SET_USEROPERATOR))
      {//系统维护人员设置指定用户的操作权限
        new UserOperatorBuss(sc,cb.toString()).sysManWriteUserOperators();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SYSGET_USERIFNO))
      {////系统管理员读取用户信息
        new UserInfoBuss(sc,cb.toString()).sysManGetUserInfo();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SYSSET_USERINFO))
      {///系统管理员设置用户信息
        new UserInfoBuss(sc,cb.toString()).sysManSetUserInfo();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_SYSGET_DUTYINFOS))
      {///读取系统职务信息
        new DutyInfoBuss(sc,cb.toString()).getDutyInfos();
      }
      else if (command_ID.equals(CommandDefine.GUANDA_DEPT_IMAGE_STATUS))
      {//读取特定部门下的用户信息和头像信息
        new UserInfoBuss(sc,cb.toString()).getDeptUserImageAndStatus();
      }
      else
      {
        System.out.println("UnKnowed Command!");
        Functions.writeLog("UnKnowed Command!");
        System.out.println("Content:" + cb.toString());
      }
    }
    PrintByteBufferInfo(temp3);
    return true;
  }
  /**
   * 打印出字符流的相关信息:
   * 1.流指针的位置 2.流指针的上限活动范围 3.字符流的容量
   * @param 需要打印的字符流
   */
  private void PrintCharBufferInfo(CharBuffer bb)
  {
    System.out.println("CharBuffer Infomation:" + bb.position() + "/"
      + bb.limit() +"/" + bb.capacity());
  }
  /**
   *打印出字节流的相关信息:
   *   1.流指针的位置 2.流指针的上限活动范围 3.字节流的容量
   * @param 需要打印的字节流
   */
  private void PrintByteBufferInfo(ByteBuffer bb)
  {
    System.out.println("ByteBuffer Infomation:" + bb.position()+"/"
      +bb.limit()+"/"+bb.capacity());
  }
  //得到数据包长度
  private int GetPacketSize(SocketChannel sc)
  {
    ByteBuffer buffer = ByteBuffer.allocate(4);
    CharBuffer cb = null;
    try
    {
      sc.read(buffer);
      int PacketSize;
      buffer.flip();
      cb = Functions.ChangeByteToChar(buffer);
      String sPacketSize = cb.toString();
      if (sPacketSize.length() < 4)
        return -1;
      int i0,i1,i2,i3,ByteCount;

      i3 = Integer.parseInt(sPacketSize.substring(3));
      i2 = Integer.parseInt(sPacketSize.substring(2,3));
      i1 = Integer.parseInt(sPacketSize.substring(1,2));
      i0 = Integer.parseInt(sPacketSize.substring(0,1));
      ByteCount = i3 + i2*10 +i1*100 + i0*1000;
      return ByteCount;
    }
    catch(NumberFormatException ex)
    {
      Functions.writeLog(ex);
      ex.printStackTrace();
      System.out.println("cb package size:" + cb.toString());
      return -1;
    }
    catch(IOException ex)
    {
      Functions.writeLog(ex);
      ex.printStackTrace();
      return -1;
    }
  }
  public static void main(String[] args)
  {
    new QQServer();
  }
}

 

package com.guanda.qqserver.util;

/**
 * <p>Title:封装好的系统公用函数 </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: GuanDa Tech</p>
 * @author Liu QinDong
 * @version 1.0
 */

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;

import java.io.DataInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.net.URL;
import java.net.MalformedURLException;

import java.util.Properties;
import java.util.Vector;

public class Functions {
  /**
   * 将字节流转换成字符流
   * @param 需要转换的字节流
   * @return 转换后的字符流
  */
  public static synchronized CharBuffer ChangeByteToChar(ByteBuffer buffer)
  {
    Charset ch = Charset.forName("GBK");
    CharsetDecoder  decoder = ch.newDecoder();
    try
    {
      CharBuffer cha = decoder.decode(buffer);
      return cha;
    }
    catch(CharacterCodingException ce)
    {
      Functions.writeLog(ce);
      System.out.println();
      return null;
    }
  }

  /**
   * 将字节流转换成字符串
   * @param 需要转换的字节流
   * @return
   */
  public static synchronized String ChangeByteToString(ByteBuffer buffer)
  {
    Charset ch = Charset.forName("GBK");
    CharsetDecoder  decoder = ch.newDecoder();
    try
    {
      CharBuffer cha = decoder.decode(buffer);
      return cha.toString();
    }
    catch(CharacterCodingException ce)
    {
      Functions.writeLog(ce);
      System.out.println();
      return null;
    }
  }

  /**
   * 将一个字符串转换成字节流
   * @param 需要转换的字符串
   * @return 转换后的字节流
  */
  public static synchronized ByteBuffer ChangeStrToByteBuffer(String source)
  {
    CharBuffer cha = CharBuffer.wrap(source);

    Charset ch = Charset.forName("GBK");
    CharsetEncoder encoder = ch.newEncoder();
    try
    {
      ByteBuffer bf = encoder.encode(cha);
      return bf;
    }
    catch(CharacterCodingException ce)
    {
      Functions.writeLog(ce);
      System.out.println("ChangeStrToByteBuffer Error:source=" + source);
      return null;
    }
  }

}

 

 

阅读更多
想对作者说点什么? 我来说一句

java NIOjava并发编程的书籍

2011年11月13日 3.87MB 下载

JavaNIO chm帮助文档

2017年10月09日 163KB 下载

JAVA NIO 实现网络编程

2011年09月27日 188KB 下载

java NIO文档

2017年12月20日 1.81MB 下载

java nio 包读取超大数据文件

2010年12月19日 26KB 下载

java NIO 中文版

2012年03月06日 2.12MB 下载

java nio 读文件

2011年12月21日 901B 下载

没有更多推荐了,返回首页

不良信息举报

JAVA NIO

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭