前段时间写了个web端与C服务端之间的通信不过用的是短连接 非堵塞的方式,一直想使用长连接,使tomcat启动的时候就和C服务端进行通信,但是一直没找到方法希望je的朋友能给点思路。先来看我现在的具体实现 
通信的核心类
public   class  newsSockBase    
{   
     private  SocketChannel sc;     
     private   final   int  MAX_LENGTH =  8192 ;     
     private  ByteBuffer r_buff ;     
     private  ByteBuffer w_buff ;     
     private   static  String host ;     
     private   static   int  port;     
  
     int      sendBufTotalLen;   
     int      sendBufLen;   
     int      sendBufStart;   
     byte []  sendBuf;   
       
     int      recvBufTotalLen;   
     int      recvBufLen;   
     int      recvBufStart;   
     byte []  recvBuf;   
       
     int      timeout;   
    String  msg;   
       
     public  newsSockBase()   
    {   
        r_buff = ByteBuffer.allocate(MAX_LENGTH);     
        w_buff = ByteBuffer.allocate(MAX_LENGTH);    
           
        sendBufTotalLen = MAX_LENGTH;   
        sendBufLen = sendBufStart =  0 ;   
        sendBuf =  new   byte [MAX_LENGTH];   
           
        recvBufTotalLen = MAX_LENGTH;   
        recvBufLen = recvBufStart =  0 ;   
        recvBuf =  new   byte [MAX_LENGTH];   
           
        timeout =  6 ;   
    }   
       
     public   void  setIPandPort(String str, int  pt)   
    {   
        host = str;   
        port  = pt;   
    }   
       
     //这两个函数一定要注意 形参是基类 而实际传入的参数是子类,到时候也是调用子类的参数来做    
     public   void  getBufFrompara(InewsDetail nD)   
    {   
         int  len = nD.encode(sendBuf, sendBufStart, sendBufTotalLen-sendBufStart-sendBufLen);   
           
        sendBufLen += len;   
           
    }   
       
     public   int  decodeBufToPara(InewsDetail nD)   
    {   
         int  len = nD.decode(recvBuf, recvBufStart, recvBufLen);   
         if  (len> 0 )    //解码正确的时候才做    
        {   
            recvBufLen -= len;   
            recvBufStart += len;           
        }   
           
         return  len;    
    }   
       
     public   void  start(InewsDetail nD)   
    {       
       
         //这里需要先根据传入的参数来    
        getBufFrompara(nD);   
           
         try  {     
            InetSocketAddress addr =  new  InetSocketAddress(host, port);     
             // 生成一个socketchannel      
            sc = SocketChannel.open();     
            sc.configureBlocking( false ); //     
             // 连接到server      
            sc.connect(addr);     
             while  (!sc.finishConnect())     
                ;     
            System.out.println( "connection has been established!…" );     
  
            // while (true)     
            {     
                 // 回射消息    // 复位,清空                
                w_buff.clear();     
                w_buff.put(sendBuf,sendBufStart,sendBufLen);     
                w_buff.flip();    // 转到最开始     
  
  
                 // 发送消息      
                 while  (w_buff.hasRemaining())     
                    sc.write(w_buff);     
                w_buff.clear();     
  
                 // 进入接收状态     
                 while  ( true )   
                {   
                     int  ss= 0 ;   
                     int  count;     
                    r_buff.clear();    
                     while (ss<timeout* 100 )   
                    {                           
                        count = sc.read(r_buff);   
                         if  (count> 0 )   
                             break ;   
                        ss++;   
                        Thread.currentThread().sleep( 10 );    
                    }     
                       
                     if  (ss==timeout)   
                    {   
                         break ;   
                    }   
                       
                    r_buff.flip();     
                       
                     //判断recvBuf能不能放下接收到的数据    
                     if  (r_buff.limit()+recvBufStart+recvBufLen>recvBufTotalLen)   
                    {   
                         //放不下了    
                         //那就先看看前面是不是有空余    
                         if  (recvBufStart> 0 )   
                        {   
                             for ( int  i= 0 ;i<recvBufStart;i++)   
                            {   
                                recvBuf  = recvBuf[i+recvBufStart];   
                            }   
                            recvBufStart = 0;   
  
                        }   
                           
                        if (r_buff.limit()+recvBufStart+recvBufLen>recvBufTotalLen)   
                        {   
                            //这个时候就是真的说数据区长度不够了,属于致命错误   
                            System.err.println("致命错误! 缓冲区长度过小!");   
                        }   
                    }   
                    else  
                    {   // 也可以转化为字符串,不过需要借助第三个变量了。    
                           
                        r_buff.get(recvBuf,recvBufStart+recvBufLen,r_buff.limit());   
                        //得到了一次数据就要试着做一次解码,如果能够解码,那就完成解码,不能则表示数据不完整,继续等待新数据   
                        //这里注意返回值 如果是0  表示数据不完整 如果是正数 就是解码的字节数 负数表示解码出错   
                        recvBufLen += r_buff.limit();   
                        if (decodeBufToPara(nD)!=0)   
                            break;   
                    }   
                        
                    System.out.println("reply is " + r_buff.limit() + " long " );     
                }   
            }     
            sc.socket().close();   
               
        } catch (IOException ioe) {     
            ioe.printStackTrace();     
        } catch (InterruptedException ie) {     
            ie.printStackTrace();     
        }     
           
        System.out.println("Exit App....... " );    
    }   
  
    public static void main(String[] args)    
    {   
        newsDetailNewsSum nDNS = new newsDetailNewsSum();   
        newsSockBase nsb = new newsSockBase();   
        nsb.setIPandPort("192.168.0.106",8888);   
        nsb.start(nDNS);   
           
        System.out.println("Exit Allllll....... " );   
    }   
  
}  
下面是报文协议的基类
//此类试图将所有的通讯协议的编解码都包含在内!按照一次交互的过程来区分   
public class newsDetail implements InewsDetail   
{   
    protected int       netErr; //用来表示是不是网络出错了,主要是超时。这个时候就不需要检查其他参数了。   
    protected int       type;   //就是对应具体的操作类型码   
    protected byte[]    StreamID=new byte[16];  //对应具体的流水号   
    protected byte[]    asyn = new byte[2];   
       
    //这个还是有问题 不能达到预计效果 需要修改   
    static private int  seq=0;  //生成流水号后2位的时候使用的   
    static private Calendar lastCa;   
       
    public newsDetail()    
    {   
        getStreamID();   
    }   
       
       
       
    public int getType() {   
        return type;   
    }   
  
  
  
    public void setType(int type) {   
        this.type = type;   
    }   
  
  
  
    //基类中的编解码函数没有作用,具体使用的编解码函数在各个子类中需要重新实现   
    //必须有返回值 因为调用者需要根据返回值做一些操作   
    //这里的参数 buf是需要填写的缓冲区  start 是缓冲区开始位置 len 是可用的缓冲区长度   
    public int encode(byte[] buf,int start,int len)   
    {   
        return 0;   
    }   
    //这里的参数 buf是需要需要解码的缓冲区  start 是缓冲区开始位置 len 是需要解码的长度   
    public int decode(byte[] buf,int start,int len)   
    {   
        return 0;   
    }   
  
    public void getStreamID()   
    {   
        Calendar ca = Calendar.getInstance();   
          int year = ca.get(Calendar.YEAR);//获取年份   
          int month=ca.get(Calendar.MONTH)+1;//获取月份    
          int day=ca.get(Calendar.DATE);//获取日   
          int minute=ca.get(Calendar.MINUTE);//分    
          int hour=ca.get(Calendar.HOUR);//小时    
          int second=ca.get(Calendar.SECOND);//秒   
          int am_pm=ca.get(Calendar.AM_PM);   
          if (am_pm==Calendar.PM)   
              hour += 12;   
          if (hour>=24)   
              hour -= 24;   
             
        System.out.println(seq);   
              
          if (lastCa!=ca)   
          {   
              lastCa = ca;   
              seq = 12;   
          }   
          else  
          {   
              seq++;   
              if (seq>=100)   
                  seq = 0;   
          }   
             
          //现在根据上面的字段组成StreamID字符串   
          //目前先使用手工的办法来写,效率高一些        
          StreamID[0] = (byte)(year/1000+'0');   
          StreamID[1] = (byte)((year-(StreamID[0]-'0')*1000)/100+'0');   
          StreamID[2] = (byte)((year-(StreamID[0]-'0')*1000-(StreamID[1]-'0')*100)/10+'0');   
          StreamID[3] = (byte)(year-(StreamID[0]-'0')*1000-(StreamID[1]-'0')*100-(StreamID[2]-'0')*10+'0');   
             
          StreamID[4] = (byte)(month/10+'0');   
          StreamID[5] = (byte)((month-(StreamID[4]-'0')*10)+'0');   
             
          StreamID[6] = (byte)(day/10+'0');   
          StreamID[7] = (byte)((day-(StreamID[6]-'0')*10)+'0');   
             
          StreamID[8] = (byte)(hour/10+'0');   
          StreamID[9] = (byte)((hour-(StreamID[8]-'0')*10)+'0');   
             
          StreamID[10] = (byte)(minute/10+'0');   
          StreamID[11] = (byte)((minute-(StreamID[10]-'0')*10)+'0');   
             
          StreamID[12] = (byte)(second/10+'0');   
          StreamID[13] = (byte)((second-(StreamID[12]-'0')*10)+'0');   
             
          StreamID[14] = (byte)(seq/10+'0');   
          StreamID[15] = (byte)((seq-(StreamID[14]-'0')*10)+'0');      
             
          System.out.println("现在时间");   
          System.out.println("用Calendar.getInstance().getTime()方式显示时间: " + ca.getTime());   
          System.out.println("用Calendar获得日期是:" + year +"年"+ month +"月"+ day + "日");         
          System.out.println("用Calendar获得时间是:" + hour +"时"+ minute +"分"+ second +"秒");   
       
             
    }   
       
  
    public static void main(String[] args)    
    {   
        {   
            newsDetail nn1 = new newsDetail();   
        }   
        try {   
            Thread.currentThread().sleep(3000);   
        } catch (InterruptedException e) {   
            // TODO Auto-generated catch block   
            e.printStackTrace();   
        }

转载于:https://www.cnblogs.com/jiangu66/p/3159667.html

javaSocket与C通信相关推荐

  1. C++ as3 socket服务端

    C++winsocket服务端,Flex as3客户端.服务端Bind绑定IP127.0.0.1端口2020,在Flex中使用Socket.connect向服务器发起链接.当Flex在本地运行的时候能 ...

  2. arduino 与java通信_ardunio+esp8266与javaSocket网络通信(好)

    ardunio+esp8266与javaSocket网络通信 功能 通过ardunio向esp8266模块发送at指令,连接上wifi,然后向服务器发送tcp连接请求,之后是与服务器进行sockt通信 ...

  3. JAVA-Socket通信笔记

    TCP 的 Java 支持 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构.交换方式.包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议.TCP 协议和 ...

  4. Java--Socket通信

    下面内容是Java开发内容的高级知识点,需要对Java中的面向对象.IO.多线程.以及网络相关知识有一定的基础.(知识永远都有深度,本章节长期更新内容) 1.网络基础知识 网络通信的条件:1.两个通信 ...

  5. silverlight java通信_Silverlight使用JavaSocket连接jabber服务器

    Silverlight使用JavaSocket连接jabber服务器 一.开发环境 Vs2010,Sl4,jdk6,MyEclipse8.5 二.Silverlight socket使用 注意事项 1 ...

  6. java socket客户端设计,基于JavaSocket多客户端并发通信聊天程序的设计与实现

    软件设计开发本栏目责任编辑:谢媛媛 基于JavaSocket多客户端并发通信聊天程序的设计与实现 莫足琴,欧阳艳阶,马康 (十堰职业技术学院计算机工程系,湖北十堰442000) 摘要:随着网络技术与计 ...

  7. 【Java高级】初探socket编程 ——JavaSocket连接与简单通信

    新学期生活开始一段时间了,要继续学习一些新的技术(这里指socket /doge),目标是尝试完成一个在线即时聊天的小程序(尽量不咕).会更新一系列socket编程的技术文章,欢迎关注交流~ 那么千里 ...

  8. JavaSocket通信

    子曰:"温故而知新,可以为师矣." 网络基础知识 两台计算机通过网络进行通信的必备条件: 1.两台计算机要有唯一的标识-IP地址 2.协议 3.相应的端口号.不同的应用程序间的通信 ...

  9. Java--Socket客户端,服务端通信

    1.客户端接受服务端的消息并打印: 客户端: import java.io.BufferedReader; import java.io.IOException; import java.io.Inp ...

最新文章

  1. what you should do if you want to exercise?
  2. 使用opensll的md5对于string进行加密
  3. visual studio2017调用SDK各个操作步骤的作用
  4. MongoDB 教程一: 安装和使用 (Mongodb启动命令mongod参数说明)
  5. 芯片人才平均薪资近万元 2020年芯片人才缺口超30万
  6. 2d shader unity 阴影_UNITY崩坏3角色渲染实践
  7. python小白从哪来开始-如何从零开始学习Python【小白入门】
  8. VBA中,可以利用下面的语句来调用Excel内置对话框
  9. Linux - vim编辑器,tmux的简单使用
  10. Dynamics AX2012 弹出Message Box
  11. 南京林业大学883数据结构本校资料
  12. 华悦网游器软件介绍及功能介绍
  13. 【Matlab应用】:相控阵天线方向图合成及波束扫描算法实现
  14. 如何高效录制和分享教学视频?我尝试了芦笋
  15. 04HTML5学习之网页设计
  16. 2022-2028年全球与中国压电薄膜传感器行业发展趋势及投资战略分析
  17. c# 指定打开某个路径下的CMD_Windows小技巧 批处理文件实现目录下文件批量打包压缩...
  18. 计算机组成原理实训重要吗,计算机组成原理实训_报告.doc
  19. C++的名字空间(很重要)
  20. 计算机网络——物理层和信道复用(频分、时分、码分)技术

热门文章

  1. 语法:MySQL中INSERT IGNORE INTO和REPLACE INTO的使用
  2. BZOJ4893: 项链分赃 BZOJ4895: 项链分赃(增强版)
  3. Linux软件安装的补充
  4. 基于I2C总线的0.96寸OLED显示屏驱动
  5. [HttpPost]和[AcceptVerbs(HttpVerbs.Post)]区别
  6. Android Tcp操作
  7. 《当程序员的那些狗日日子》(十五)首次接单
  8. 如何安排vixta之三-Installing来源劈脸安排
  9. 汇总Javascript各种判断脚本(javascript经典例子)
  10. 【Groovy】编译时元编程 ( 编译时方法注入 | 使用 buildFromSpec、buildFromString、buildFromCode 进行方法注入 )