javaSocket与C通信
前段時間寫了個web端與C服務端之間的通信不過用的是短連接?非堵塞的方式,一直想使用長連接,使tomcat啟動的時候就和C服務端進行通信,但是一直沒找到方法希望je的朋友能給點思路。先來看我現(xiàn)在的具體實現(xiàn)?
通信的核心類
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;???
????}???
???????
???? //這兩個函數(shù)一定要注意?形參是基類?而實際傳入的參數(shù)是子類,到時候也是調(diào)用子類的參數(shù)來做? ??
???? 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)???
????{???????
???????
???????? //這里需要先根據(jù)傳入的參數(shù)來? ??
????????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();??? //?轉(zhuǎn)到最開始?? ??
??
??
???????????????? //?發(fā)送消息??? ??
???????????????? while ?(w_buff.hasRemaining())?????
????????????????????sc.write(w_buff);?????
????????????????w_buff.clear();?????
??
???????????????? //?進入接收狀態(tài)?? ??
???????????????? 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能不能放下接收到的數(shù)據(jù)? ??
???????????????????? 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)???
????????????????????????{???
????????????????????????????//這個時候就是真的說數(shù)據(jù)區(qū)長度不夠了,屬于致命錯誤???
????????????????????????????System.err.println("致命錯誤!?緩沖區(qū)長度過小!");???
????????????????????????}???
????????????????????}???
????????????????????else??
????????????????????{???//?也可以轉(zhuǎn)化為字符串,不過需要借助第三個變量了。????
???????????????????????????
????????????????????????r_buff.get(recvBuf,recvBufStart+recvBufLen,r_buff.limit());???
????????????????????????//得到了一次數(shù)據(jù)就要試著做一次解碼,如果能夠解碼,那就完成解碼,不能則表示數(shù)據(jù)不完整,繼續(xù)等待新數(shù)據(jù)???
????????????????????????//這里注意返回值?如果是0??表示數(shù)據(jù)不完整?如果是正數(shù)?就是解碼的字節(jié)數(shù)?負數(shù)表示解碼出錯???
????????????????????????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.......?"?);???
????}???
??
}??
下面是報文協(xié)議的基類
//此類試圖將所有的通訊協(xié)議的編解碼都包含在內(nèi)!按照一次交互的過程來區(qū)分???
public?class?newsDetail?implements?InewsDetail???
{???
????protected?int???????netErr;?//用來表示是不是網(wǎng)絡出錯了,主要是超時。這個時候就不需要檢查其他參數(shù)了。???
????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;???
????}???
??
??
??
????//基類中的編解碼函數(shù)沒有作用,具體使用的編解碼函數(shù)在各個子類中需要重新實現(xiàn)???
????//必須有返回值?因為調(diào)用者需要根據(jù)返回值做一些操作???
????//這里的參數(shù)?buf是需要填寫的緩沖區(qū)??start?是緩沖區(qū)開始位置?len?是可用的緩沖區(qū)長度???
????public?int?encode(byte[]?buf,int?start,int?len)???
????{???
????????return?0;???
????}???
????//這里的參數(shù)?buf是需要需要解碼的緩沖區(qū)??start?是緩沖區(qū)開始位置?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;???
??????????}???
?????????????
??????????//現(xiàn)在根據(jù)上面的字段組成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("現(xiàn)在時間");???
??????????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();???
????????}????
? ? ? ??
轉(zhuǎn)載于:https://www.cnblogs.com/jiangu66/p/3159667.html
總結
以上是生活随笔為你收集整理的javaSocket与C通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓄电池容量和环境温度的关系
- 下一篇: adb shell root