안 드 로 이 드 는 Socket 과 서버 를 통 해 통신 합 니 다(demo 첨부)

18216 단어 android소켓 통신
Android 는 Socket 과 서버 를 통 해 통신 하 는 데 자주 사용 되 는 통신 방식 으로 시간 이 비교적 촉박 하 다.대체적인 사 고 를 말 하고 socket 을 사용 하여 통신 하 는 사람 을 도 울 수 있 기 를 바란다.
(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
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기