안 드 로 이 드 는 Socket 과 서버 를 통 해 통신 합 니 다(demo 첨부)
(1)스 레 드 를 열 어 메 시 지 를 보 냅 니 다. SocketOutputThread
메 시 지 는 대기 열 에 놓 여 있 습 니 다.메시지 가 있 으 면 대기 열 에 들 어가 서 스 레 드 를 깨 우 고 메 시 지 를 보 내 며 성공 적 인 반전 여 부 를 피드백 합 니 다.
(2)서버 메 시 지 를 받 기 위해 스 레 드 를 엽 니 다.SocketInputThread
데 이 터 를 계속 받 고 배터리 의 전 기 를 낭비 하 는 것 을 방지 하기 위해 NIO 방식 으로 socket 의 데 이 터 를 읽 는 것 이 본 고의 관건 이다.
(3)스 레 드 를 켜 고 심장 박동 을 하 며 socket 연결 이 끊 어 지 는 것 을 방지 합 니 다.SocketHeartThread
(4)SocketThreadManager 를 구축 하여 상기 세 개의 thread 를 관리 합 니 다.
(5)TCPClient 구축 소켓 메시지 보 내기
NIO 방식 으로 TCP 를 실현 합 니 다.특히 서버 의 데 이 터 를 받 을 때 스 레 드 를 쓰 지 않 고 정시 에 읽 을 수 있 습 니 다.
데모 캡 처
주요 코드 는 다음 과 같 습 니 다.상세 코드 는 첨부 파일 에 있 습 니 다.
SocketOutPutThread 클래스
package com.example.socketblockdemo;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
/**
*
*
* @author way
*
*/
public class SocketOutputThread extends Thread
{
private boolean isStart = true;
private static String tag = "socketOutputThread";
private List<MsgEntity> sendMsgList;
public SocketOutputThread( )
{
sendMsgList = new CopyOnWriteArrayList<MsgEntity>();
}
public void setStart(boolean isStart)
{
this.isStart = isStart;
synchronized (this)
{
notify();
}
}
// socket
public boolean sendMsg(byte[] msg) throws Exception
{
if (msg == null)
{
CLog.e(tag, "sendMsg is null");
return false;
}
try
{
TCPClient.instance().sendMsg(msg);
} catch (Exception e)
{
throw (e);
}
return true;
}
// socket
public void addMsgToSendList(MsgEntity msg)
{
synchronized (this)
{
this.sendMsgList.add(msg);
notify();
}
}
@Override
public void run()
{
while (isStart)
{
// list
synchronized (sendMsgList)
{
//
for (MsgEntity msg : sendMsgList)
{
Handler handler = msg.getHandler();
try
{
sendMsg(msg.getBytes());
sendMsgList.remove(msg);
// , hander
if (handler != null)
{
Message message = new Message();
message.obj = msg.getBytes();
message.what =1;
handler.sendMessage(message);
// handler.sendEmptyMessage(1);
}
} catch (Exception e)
{
e.printStackTrace();
CLog.e(tag, e.toString());
// , hander
if (handler != null)
{
Message message = new Message();
message.obj = msg.getBytes();
message.what = 0;;
handler.sendMessage(message);
}
}
}
}
synchronized (this)
{
try
{
wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}// ,
}
}
}
}
SocketInputThread
package com.example.socketblockdemo;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import android.content.Intent;
import android.text.TextUtils;
/**
*
*
* @author way
*
*/
public class SocketInputThread extends Thread
{
private boolean isStart = true;
private static String tag = "socket";
// private MessageListener messageListener;//
public SocketInputThread()
{
}
public void setStart(boolean isStart)
{
this.isStart = isStart;
}
@Override
public void run()
{
while (isStart)
{
// , socket
if (NetManager.instance().isNetworkConnected())
{
if (!TCPClient.instance().isConnect())
{
CLog.e(tag, "TCPClient connet server is fail read thread sleep second" +Const.SOCKET_SLEEP_SECOND );
try
{
sleep(Const.SOCKET_SLEEP_SECOND * 1000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
readSocket();
// , ,sleep , , sleep
CLog.e("socket","TCPClient.instance().isConnect() " + TCPClient.instance().isConnect() );
}
}
}
public void readSocket()
{
Selector selector = TCPClient.instance().getSelector();
if (selector == null)
{
return;
}
try
{
// ,
while (selector.select() > 0)
{
for (SelectionKey sk : selector.selectedKeys())
{
// SelectionKey Channel
if (sk.isReadable())
{
// NIO Channel
SocketChannel sc = (SocketChannel) sk.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
try
{
sc.read(buffer);
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
// continue;
}
buffer.flip();
String receivedString = "";
//
try
{
receivedString = Charset.forName("UTF-8")
.newDecoder().decode(buffer).toString();
CLog.e(tag, receivedString);
Intent i = new Intent(Const.BC);
i.putExtra("response", receivedString);
MainActivity.s_context.sendBroadcast(i );
} catch (CharacterCodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
buffer.clear();
buffer = null;
try
{
//
sk.interestOps(SelectionKey.OP_READ);
// SelectionKey
selector.selectedKeys().remove(sk);
} catch (CancelledKeyException e)
{
e.printStackTrace();
}
}
}
}
// selector.close();
// TCPClient.instance().repareRead();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClosedSelectorException e2)
{
}
}
}
SocketHeartHread 심리 류
package com.example.socketblockdemo;
import java.io.IOException;
import android.text.TextUtils;
class SocketHeartThread extends Thread
{
boolean isStop = false;
boolean mIsConnectSocketSuccess = false;
static SocketHeartThread s_instance;
private TCPClient mTcpClient = null;
static final String tag = "SocketHeartThread";
public static synchronized SocketHeartThread instance()
{
if (s_instance == null)
{
s_instance = new SocketHeartThread();
}
return s_instance;
}
public SocketHeartThread()
{
TCPClient.instance();
//
// mIsConnectSocketSuccess = connect();
}
public void stopThread()
{
isStop = true;
}
/**
* socket , Socket
*
* @return
*/
private boolean reConnect()
{
return TCPClient.instance().reConnect();
}
public void run()
{
isStop = false;
while (!isStop)
{
//
boolean canConnectToServer = TCPClient.instance().canConnectToServer();
if(canConnectToServer == false){
reConnect();
}
try
{
Thread.sleep(Const.SOCKET_HEART_SECOND * 1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
스 레 드 관리 클래스
package com.example.socketblockdemo;
import android.os.Handler;
import android.text.TextUtils;
public class SocketThreadManager
{
private static SocketThreadManager s_SocketManager = null;
private SocketInputThread mInputThread = null;
private SocketOutputThread mOutThread = null;
private SocketHeartThread mHeartThread = null;
//
public static SocketThreadManager sharedInstance()
{
if (s_SocketManager == null)
{
s_SocketManager = new SocketThreadManager();
s_SocketManager.startThreads();
}
return s_SocketManager;
}
// ,
private SocketThreadManager()
{
mHeartThread = new SocketHeartThread();
mInputThread = new SocketInputThread();
mOutThread = new SocketOutputThread();
}
/**
*
*/
private void startThreads()
{
mHeartThread.start();
mInputThread.start();
mInputThread.setStart(true);
mOutThread.start();
mInputThread.setStart(true);
// mDnsthread.start();
}
/**
* stop
*/
public void stopThreads()
{
mHeartThread.stopThread();
mInputThread.setStart(false);
mOutThread.setStart(false);
}
public static void releaseInstance()
{
if (s_SocketManager != null)
{
s_SocketManager.stopThreads();
s_SocketManager = null;
}
}
public void sendMsg(byte [] buffer, Handler handler)
{
MsgEntity entity = new MsgEntity(buffer, handler);
mOutThread.addMsgToSendList(entity);
}
}
TCPClient,NIO 방식 으로 구축
package com.example.socketblockdemo;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
/**
* NIO TCP
*
*/
public class TCPClient
{
//
private Selector selector;
//
SocketChannel socketChannel;
// Ip
private String hostIp;
//
private int hostListenningPort;
private static TCPClient s_Tcp = null;
public boolean isInitialized = false;
public static synchronized TCPClient instance()
{
if (s_Tcp == null)
{
s_Tcp = new TCPClient(Const.SOCKET_SERVER,
Const.SOCKET_PORT);
}
return s_Tcp;
}
/**
*
*
* @param HostIp
* @param HostListenningPort
* @throws IOException
*/
public TCPClient(String HostIp, int HostListenningPort)
{
this.hostIp = HostIp;
this.hostListenningPort = HostListenningPort;
try
{
initialize();
this.isInitialized = true;
} catch (IOException e)
{
this.isInitialized = false;
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e)
{
this.isInitialized = false;
e.printStackTrace();
}
}
/**
*
*
* @throws IOException
*/
public void initialize() throws IOException
{
boolean done = false;
try
{
//
socketChannel = SocketChannel.open(new InetSocketAddress(hostIp,
hostListenningPort));
if (socketChannel != null)
{
socketChannel.socket().setTcpNoDelay(false);
socketChannel.socket().setKeepAlive(true);
// socket timeout
socketChannel.socket().setSoTimeout(
Const.SOCKET_READ_TIMOUT);
socketChannel.configureBlocking(false);
//
selector = Selector.open();
if (selector != null)
{
socketChannel.register(selector, SelectionKey.OP_READ);
done = true;
}
}
} finally
{
if (!done && selector != null)
{
selector.close();
}
if (!done)
{
socketChannel.close();
}
}
}
static void blockUntil(SelectionKey key, long timeout) throws IOException
{
int nkeys = 0;
if (timeout > 0)
{
nkeys = key.selector().select(timeout);
} else if (timeout == 0)
{
nkeys = key.selector().selectNow();
}
if (nkeys == 0)
{
throw new SocketTimeoutException();
}
}
/**
*
*
* @param message
* @throws IOException
*/
public void sendMsg(String message) throws IOException
{
ByteBuffer writeBuffer = ByteBuffer.wrap(message.getBytes("utf-8"));
if (socketChannel == null)
{
throw new IOException();
}
socketChannel.write(writeBuffer);
}
/**
*
*
* @param bytes
* @throws IOException
*/
public void sendMsg(byte[] bytes) throws IOException
{
ByteBuffer writeBuffer = ByteBuffer.wrap(bytes);
if (socketChannel == null)
{
throw new IOException();
}
socketChannel.write(writeBuffer);
}
/**
*
* @return
*/
public synchronized Selector getSelector()
{
return this.selector;
}
/**
* Socket
*
* @return
*/
public boolean isConnect()
{
boolean isConnect = false;
if (this.isInitialized)
{
isConnect = this.socketChannel.isConnected();
}
return isConnect;
}
/**
* socket
*
* @return
*/
public boolean reConnect()
{
closeTCPSocket();
try
{
initialize();
isInitialized = true;
} catch (IOException e)
{
isInitialized = false;
e.printStackTrace();
}
catch (Exception e)
{
isInitialized = false;
e.printStackTrace();
}
return isInitialized;
}
/**
* , socket
*
* @return
*/
public boolean canConnectToServer()
{
try
{
if (socketChannel != null)
{
socketChannel.socket().sendUrgentData(0xff);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
/**
* socket
*/
public void closeTCPSocket()
{
try
{
if (socketChannel != null)
{
socketChannel.close();
}
} catch (IOException e)
{
}
try
{
if (selector != null)
{
selector.close();
}
} catch (IOException e)
{
}
}
/**
* , selector,
*/
public synchronized void repareRead()
{
if (socketChannel != null)
{
try
{
selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_READ);
} catch (ClosedChannelException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
어떻게 사용 합 니까?
// , handler
SocketThreadManager.sharedInstance().sendMsg(str.getBytes(), handler);
코드 다운로드:demo이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.