Android编程双工tcp客户端中应用RxJavaWord文件下载.docx
《Android编程双工tcp客户端中应用RxJavaWord文件下载.docx》由会员分享,可在线阅读,更多相关《Android编程双工tcp客户端中应用RxJavaWord文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
importjava.io.InputStream;
importjava.io.OutputStream;
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<
NetSendParameter>
sendListCache;
sendList;
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<
NetAddress>
(){
//@Oerride
//publicvoidsubscribe(FlowableEmitter<
e)throwsException{
//Log.e(TAG_LOG,"
subscribe!
!
);
//e.onNext(netAddress);
//e.onComplete();
//}
//},BackpressureStrategy.DROP).
//observeOn(Schedulers.io()).
//subscribe(newConsumer<
//@Override
//publicvoidaccept(NetAddressnetAddress1)throwsException{
accept!
//startMakeConnect(netAddress1);
//});
privatevoidstartMakeConnect(NetAddressnetAddress){
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!
}catch(IOExceptione){
e.printStackTrace();
privatevoidtcpSocketClose(){
isConnected=false;
tcpSocket.close();
Log.i(TAG_LOG,"
断开连接"
privatevoidunlockReceiveThread(){
synchronized(lockReceiveThread){
lockReceiveThread.notifyAll();
*关闭连接
publicvoidclose(){
e.onNext("
tcpSocketClose());
*当前是否连接.
*@return连接返回true,失败返回false
publicbooleanisConnected(){
returnisConnected;
*得到服务器ip
*@return服务器ip
publicStringgetServerIp(){
returnserverIp;
*得到服务器端口
*@return服务器端口
publicintgetServerPort(){
returnserverPort;
*发送
*@paramnetSendParameter发送参数
publicvoidsend(NetSendParameternetSendParameter){
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();
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();
privatevoidlockReceiveThread(){
lockReceiveThread.wait();
}catch(InterruptedExceptione){
privatevoidexceptionClose(){
tcpSocket.isClosed()){
closed1111111111!
booleanisExceptionClose=isConnected;
if(isExceptionClose){
Events.TcpExceptionCloseevent=newEvents.TcpExceptionClose();
tcpSocket.isConnected()){
disconnect11111111111!
privateclassSendThreadimplementsRunnable{
clearCache();
sendList.clear();
lockThread();
copyCache();
sendList.isEmpty()){
sendFrame();
privatevoidclearCache(){
sendListCear();
privatevoidlockThread(){
lockSendThread.wait();
privatevoidcopyCache(){
sendListCacheLock.readLock().lock();
if(sendListCache.isEmpty()){
sendListCacheLock.readLock().unlock();
sendList.addAll(sendListCache);
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>
arr[j++]=(byte)netSendParameter.cmd;
if(netSendParameter.frameIndex==0){
intframeIndex=FrameIndex.getInstance().get();
arr[j++]=(byte)(frameIndex>
arr[j++]=(byte)frameIndex;
FrameIndex.getInstance().increment();
arr[j++]=(byte)(netSendParameter.frameIndex>
arr[j++]=(byte)netSendParameter.frameIndex;
//报文长度
arr[j++]=(byte)(netSendParameter.length>
arr[j++]=(byte)netSendParameter.length;
intcrc=Crc16.calc(netSendParameter.frameBody,0,netSendParameter.length);
arr[j++]=(byte)(crc>
arr[j++]=(byte)crc;
//正文
for(inti=0;
i<
netSendParameter.length;
i++){
arr[j++]=netSendParameter.frameBody[i];
outputStream.write(arr,0,j);
privateclassNetAddress{
Stringip;
intport;
NetAddress(Stringip,intport){
this.ip=ip;
this.port=port;
测试代码:
创建连接:
TcpClient.getInstance().makeConnect("
115.28.86.171"
21801);
断开连接:
TcpClient.getInstance().close();
发送数据:
NetSendParameterparameter=newNetSendParameter();
parameter.cmd=3;
TcpClient.getInstance().send(parameter);
接收总线消息:
RxBus.getInstance().toObserverable(Events.TcpMakeConnectSuccess.clas