Android编程双工tcp客户端中应用RxJava.docx
- 文档编号:7950634
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:14
- 大小:17.22KB
Android编程双工tcp客户端中应用RxJava.docx
《Android编程双工tcp客户端中应用RxJava.docx》由会员分享,可在线阅读,更多相关《Android编程双工tcp客户端中应用RxJava.docx(14页珍藏版)》请在冰豆网上搜索。
Android编程双工tcp客户端中应用RxJava
Android编程:
双工tcp客户端中应用RxJava
源码:
Events.Java
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
packagemon;
import.DatagramPacket;
publicclassEvents{
privateEvents(){
}
publicstaticclassUdpReceiveFrame{
publicDatagramPacketdatagramPacket;
}
publicstaticclassTcpReceiveFrame{
publicDatagramPacketdatagramPacket;
}
publicstaticclassTcpMakeConnectSuccess{
}
publicstaticclassTcpExceptionClose{
}
}
TcpClient.Java
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
package;
importandroid.util.Log;
importcom.bazhangkeji.classroom.Config;
importmon.Crc16;
importmon.Events;
importmon.RxBus;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
import.DatagramPacket;
import.InetSocketAddress;
import.Socket;
import.SocketAddress;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.locks.ReadWriteLock;
importjava.util.concurrent.locks.ReentrantReadWriteLock;
importio.reactivex.BackpressureStrategy;
importio.reactivex.Flowable;
importio.reactivex.schedulers.Schedulers;
publicclassTcpClientimplementsConfig,Protocol,Runnable{
privatestaticfinalStringTAG_LOG="TcpClient";
privatestaticfinalintMAX_FRAME_LENGTH=2048;
privatestaticfinalintCONNECT_TIME_OUT=3000;
privatestaticTcpClienttcpClient;
privatebooleanisConnected=false;
privateSockettcpSocket;
privateInputStreaminputSteam;
privateOutputStreamoutputStream;
privateStringserverIp="";
privateintserverPort;
privateList
privateList
privateReadWriteLocksendListCacheLock;
//线程锁:
当前发送线程全部发送完成后就自锁等待
privatefinalbyte[]lockSendThread=newbyte[0];
//线程锁:
当前不需要侦听则自锁等待
privatefinalbyte[]lockReceiveThread=newbyte[0];
publicstaticTcpClientgetInstance(){
if(tcpClient==null){
tcpClient=newTcpClient();
newThread(TcpClient.getInstance()).start();
}
returntcpClient;
}
privateTcpClient()
{
sendListCache=newArrayList<>();
sendList=newArrayList<>();
sendListCacheLock=newReentrantReadWriteLock();
newThread(newSendThread()).start();
}
/**
*连接服务器
*@paramip:
服务器ip
*@paramport:
服务器端口
*/
publicsynchronizedvoidmakeConnect(Stringip,intport){
if(isConnected){
if(this.serverIp.equals(ip)&&this.serverPort==port){
Events.TcpMakeConnectSuccessevent=newEvents.TcpMakeConnectSuccess();
RxBus.getInstance().send(event);
return;
}
}
Flowable.create(e->{
e.onNext(newNetAddress(ip,port));
e.onComplete();
},BackpressureStrategy.DROP)
.observeOn(Schedulers.io())
.subscribe(t->startMakeConnect((NetAddress)t));
//NetAddressnetAddress=newNetAddress(ip,port);
//Flowable.create(newFlowableOnSubscribe
//@Oerride
//publicvoidsubscribe(FlowableEmitter
//Log.e(TAG_LOG,"subscribe!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
");
//e.onNext(netAddress);
//e.onComplete();
//}
//},BackpressureStrategy.DROP).
//observeOn(Schedulers.io()).
//subscribe(newConsumer
//@Override
//publicvoidaccept(NetAddressnetAddress1)throwsException{
//Log.e(TAG_LOG,"accept!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
");
//startMakeConnect(netAddress1);
//}
//});
}
privatevoidstartMakeConnect(NetAddressnetAddress){
if(isConnected){
tcpSocketClose();
}
try{
tcpSocket=newSocket();
SocketAddressaddress=newInetSocketAddress(netAddress.ip,netAddress.port);
tcpSocket.connect(address,CONNECT_TIME_OUT);
inputSteam=tcpSocket.getInputStream();
outputStream=tcpSocket.getOutputStream();
isConnected=true;
serverIp=netAddress.ip;
serverPort=netAddress.port;
unlockReceiveThread();
Log.e(TAG_LOG,"makeconnectsuccess!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
");
Events.TcpMakeConnectSuccessevent=newEvents.TcpMakeConnectSuccess();
RxBus.getInstance().send(event);
}catch(IOExceptione){
e.printStackTrace();
}
}
privatevoidtcpSocketClose(){
isConnected=false;
try{
tcpSocket.close();
Log.i(TAG_LOG,"断开连接");
}catch(IOExceptione){
e.printStackTrace();
}
}
privatevoidunlockReceiveThread(){
synchronized(lockReceiveThread){
lockReceiveThread.notifyAll();
}
}
/**
*关闭连接
*/
publicvoidclose(){
if(isConnected){
Flowable.create(e->{
e.onNext("");
e.onComplete();
},BackpressureStrategy.DROP)
.observeOn(Schedulers.io())
.subscribe(t->tcpSocketClose());
}
}
/**
*当前是否连接.
*@return连接返回true,失败返回false
*/
publicbooleanisConnected(){
returnisConnected;
}
/**
*得到服务器ip
*@return服务器ip
*/
publicStringgetServerIp(){
returnserverIp;
}
/**
*得到服务器端口
*@return服务器端口
*/
publicintgetServerPort(){
returnserverPort;
}
/**
*发送
*@paramnetSendParameter发送参数
*/
publicvoidsend(NetSendParameternetSendParameter){
if(isConnected){
sendListCacheLock.writeLock().lock();
sendListCache.add(netSendParameter);
sendListCacheLock.writeLock().unlock();
unlockSendThread();
}
}
privatevoidunlockSendThread(){
synchronized(lockSendThread){
lockSendThread.notifyAll();
}
}
@Override
publicvoidrun(){
byte[]bufferReceive=newbyte[MAX_FRAME_LENGTH];
DatagramPacketreceiveFrame=newDatagramPacket(bufferReceive,MAX_FRAME_LENGTH);
while(true){
if(!
isConnected){
lockReceiveThread();
}
try{
intlength=inputSteam.read(receiveFrame.getData());
if(th>0){
receiveFrame.setLength(length);
if(FilterFrame.filter(receiveFrame)){
Events.TcpReceiveFrametcpReceiveFrame=newEvents.TcpReceiveFrame();
tcpReceiveFrame.datagramPacket=receiveFrame;
RxBus.getInstance().send(tcpReceiveFrame);
}
}else{
exceptionClose();
}
}catch(IOExceptione){
e.printStackTrace();
exceptionClose();
}
}
}
privatevoidlockReceiveThread(){
synchronized(lockReceiveThread){
try{
lockReceiveThread.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
privatevoidexceptionClose(){
if(!
tcpSocket.isClosed()){
Log.i(TAG_LOG,"closed1111111111!
!
!
!
");
booleanisExceptionClose=isConnected;
tcpSocketClose();
if(isExceptionClose){
Events.TcpExceptionCloseevent=newEvents.TcpExceptionClose();
RxBus.getInstance().send(event);
}
}
if(!
tcpSocket.isConnected()){
Log.i(TAG_LOG,"disconnect11111111111!
!
!
!
");
}
}
privateclassSendThreadimplementsRunnable{
@Override
publicvoidrun(){
while(true){
if(!
isConnected){
clearCache();
sendList.clear();
lockThread();
}
copyCache();
if(!
sendList.isEmpty()){
sendFrame();
sendList.clear();
}else{
lockThread();
}
}
}
privatevoidclearCache(){
sendListCacheLock.writeLock().lock();
sendListCear();
sendListCacheLock.writeLock().unlock();
}
privatevoidlockThread(){
synchronized(lockSendThread){
try{
lockSendThread.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
privatevoidcopyCache(){
sendListCacheLock.readLock().lock();
if(sendListCache.isEmpty()){
sendListCacheLock.readLock().unlock();
}else{
sendList.addAll(sendListCache);
sendListCacheLock.readLock().unlock();
clearCache();
}
}
privatevoidsendFrame(){
for(NetSendParameterparameter:
sendList){
send(parameter);
}
}
privatevoidsend(NetSendParameternetSendParameter){
byte[]arr=newbyte[MAX_FRAME_LENGTH];
intj=0;
arr[j++]=(byte)(FRAME_HEAD>>8);
arr[j++]=(byte)FRAME_HEAD;
arr[j++]=(byte)PROTOCOL_VERSION_CODE;
arr[j++]=(byte)(netSendParameter.cmd>>8);
arr[j++]=(byte)netSendParameter.cmd;
if(netSendParameter.frameIndex==0){
intframeIndex=FrameIndex.getInstance().get();
arr[j++]=(byte)(frameIndex>>8);
arr[j++]=(byte)frameIndex;
FrameIndex.getInstance().increment();
}else{
arr[j++]=(byte)(netSendParameter.frameIndex>>8);
arr[j++]=(byte)netSendParameter.frameIndex;
}
//报文长度
arr[j++]=(byte)(netSendParameter.length>>8);
arr[j++]=(byte)netSendParameter.length;
intcrc=Crc16.calc(netSendParameter.frameBody,0,netSendParameter.length);
arr[j++]=(byte)(crc>>8);
arr[j++]=(byte)crc;
//正文
for(inti=0;i arr[j++]=netSendParameter.frameBody[i]; } try{ outputStream.write(arr,0,j); }catch(IOExceptione){ e.printStackTrace(); tcpSocketClose(); } } } privateclassNetAddress{ Stringip; intport; NetAddress(Stringip,intport){ this.ip=ip; this.port=port; } } } 测试代码: 创建连接: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 TcpClient.getInstance().makeConnect("115.28.86.171",21801); 断开连接: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 TcpClient.getInstance().close(); 发送数据: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 NetSendParameterparameter=newNetSendParameter(); parameter.cmd=3; TcpClient.getInstance().send(parameter); 接收总线消息: [java]viewplaincopy在CODE上查看代码片派生到我的代码片 RxBus.getInstance().toObserverable(Events.TcpMakeConnectSuccess.clas
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 编程 双工 tcp 客户端 应用 RxJava