如何干净的实现Android/Java Socket 长连接通信

 我来答
小疤小刀
2017-05-17 · TA获得超过251个赞
知道小有建树答主
回答量:150
采纳率:0%
帮助的人:102万
展开全部

Java Socket通信有很多的时候需要我们不断的学习。方面效率虽然不及C与C++但它以灵活语言优势,为大家广为使用。 本文就对在使用java做通信方面程序时候应改注意问题做以说明。

1.长连接、短链接只是针对客户端而言,服务器无所谓长、短;

2.无论同步或者异步通信,发送之后务必要又响应回复,确认收到,负责进行一定范围内重发,例如重发三次;

3.长连接服务器与客户端之间务必需要心跳探测,由客户端主动发起;

4.短连接服务器通用代码:

package com.biesan.sms.gate.unioncom.communication;  
    import com.biesan.commons.Constants;  
    import com.biesan.commons.util.CodeUtil;  
    import com.biesan.sms.gate.unioncom.data.*;  
    import com.biesan.sms.gate.unioncom.util.GateInfo;  
    import java.net.*;  
    import java.io.*;  
    import java.util.*;  
    import org.apache.log4j.*;  
    import spApi.*;  
    public class UnioncomDeliver extends Thread {  
    // stop flag  
    private boolean unInterrupt = true;  
    private boolean unErr = true;  
    //private boolean closeSocketFlag = false;  
    // server socket  
    private ServerSocket serverSo = null;  
    // current socket  
    private Socket so = null 
    private OutputStream output = null;  
    private InputStream input = null;  
    // gate command  
    private SGIP_Command tmpCmd = null;  
    private SGIP_Command cmd = null;  
    private Bind bind = null;  
    private BindResp bindResp = null;  
    //private Unbind unBind = null;  
    private UnbindResp unBindResp = null;  
    private boolean unAcceptErrorFlag = true;  
    Logger unioncomLog = Logger.getLogger(Unioncom
    Deliver.class.getName());  
    public UnioncomDeliver() {  
    }  
    public void run() {  
    unioncomLog.info("Start...");  
    while (unInterrupt) {  
    this.initServer();  
    this.startServices();  
    while (this.unAcceptErrorFlag) {  
    try {  
    //接受连接请求  
    unioncomLog.info("before accept connection!....... 
    FreeMemroy :" + Runtime.getRuntime().freeMemory());  
    this.acceptConnection();  
    unioncomLog.info("after accept connection!....... 
    FreeMemroy :" + Runtime.getRuntime().freeMemory());  
    while (unErr) {  
    cmd = new Command();  
    unioncomLog.info("before read command from stream
    ........... FreeMemroy: " + Runtime.getRuntime().
    freeMemory());  
    tmpCmd = cmd.read(input);  
    unioncomLog.info("after read command from stream " + 
    getCommandString(cmd.getCommandID()) + " FreeMemroy: " + 
    Runtime.getRuntime().freeMemory());  
    if (tmpCmd == null) {  
    unErr = false;  
    break;  
    }  
    switch (cmd.getCommandID()) {  
    // biad ready communication  
    case SGIP_Command.ID_SGIP_BIND: {  
    this.dealBind();  
    break;  
    }// exit bind  
    case SGIP_Command.ID_SGIP_UNBIND: {  
    this.dealUnBind();  
    unioncomLog.info("after unbind connection!....... 
    FreeMemroy :" + Runtime.getRuntime().freeMemory());  
    break;  
    }// deliver  
    ....  
    default : //错误的命令字  
    break;  
    }// switch  
    }// while(unErr)  
    } catch (Exception e) {  
    unioncomLog.error("Unioncom Recv Service Error"  
    + e.getMessage());   
    } finally {  
    if (this.so != null) {  
    this.closeSocket();  
    }  
    this.unErr = true;  
    }  
    }// while (this.unAcceptErrorFlag)  
    try {  
    this.closeServerSocket();  
    sleep(200);// sleep  
    } catch (InterruptedException ie) {  
    }  
    }// while(unInterrupt)  
    }  
    private String getCommandString(int cmd){  
    switch (cmd) {  
    // biad ready communication  
    case SGIP_Command.ID_SGIP_BIND: {  
    return " BIND COMMAND ";   
    }// exit bind  
    case SGIP_Command.ID_SGIP_UNBIND: {  
    return " UNBIND COMMAND ";   
    }// deliver  
    case ...  
    default:  
    return " UNKNOWN COMMAND";   
    }  
    }  
    private void dealBind() {  
    try {  
    bind = new Bind(tmpCmd);  
    if (bind.readbody() != 0) {  
    unioncomLog.warn("Read Bind error");  
    this.unErr = false;  
    }  
    bindResp = new BindResp(tmpCmd.getMsgHead());  
    bindResp.SetResult(0);  
    bindResp.write(output);  
    unioncomLog.debug("Bind success!");  
    } catch (Exception e) {  
    unioncomLog.error("Dela Union Recv Bind Error!" + 
    e.getMessage());  
    this.unErr = false;  
    }  
    }  
    private void dealUnBind() {  
    try {  
    //unBind = (Unbind) tmpCmd;  
    unBindResp = new UnbindResp(tmpCmd.getMsgHead());  
    unBindResp.write(output);  
    unioncomLog.debug("UnBind success!");  
    } catch (Exception e) {  
    unioncomLog.warn("Unbind error!" + e.getMessage());  
    }  
    this.unErr = false;  
    }  
    private void startServices() {  
    boolean unStartServices = true;  
    while (unStartServices) {  
    try {  
    serverSo = new ServerSocket(ugInfo.getLocalServerPort(), 5,  
    InetAddress.getByName(ugInfo.getLocalIpAdd()));  
    //serverSo.setSoTimeout(60000);  
    unStartServices = false;   
    unioncomLog.info("Create union recv socket Ok!");  
    } catch (IOException e) {  
    unioncomLog.warn("Create union recv socket error!"  
    + e.getMessage());  
    unStartServices = true;  
    UnioncomSubmit.thrSlp(3000);  
    }  
    }  
    }  
    private void acceptConnection() {  
    // Accept 失败  
    try {   
    so = serverSo.accept();  
    so.setSoTimeout(10000);  
    } catch (Exception e) {  
    unioncomLog.warn("Accept Error!" + e.getMessage());  
    this.closeServerSocket();  
    this.unAcceptErrorFlag = false;  
    this.unErr=false;  
    }  
    // Accept成功  
    try {  
    input = so.getInputStream();  
    output = so.getOutputStream();  
    } catch (IOException e) {  
    unioncomLog.warn("Get I/O stream Error!" + e.getMessage());  
    this.closeService();  
    this.unAcceptErrorFlag = false;  
    this.unErr=false;  
    }  
    }  
    private void closeSocket() {  
    try {  
    so.close();  
    unioncomLog.info("Socket Close Success!!!");  
    } catch (Exception e) {  
    unioncomLog.error("Socket Close Failure!!!" + e.getMessage());  
    }  
    }  
    private void closeServerSocket() {  
    try {  
    serverSo.close();  
    unioncomLog.info("ServerSocket Close Success!!!");  
    } catch (Exception e) {  
    unioncomLog  
    .error("ServerSocket Close Failure!!!" + e.getMessage());  
    }  
    }  
    private void closeService() {  
    this.closeSocket();  
    this.closeServerSocket();  
    }  
    private void initServer() {  
    this.bind = null;  
    this.bindResp = null;  
    //this.unBind = null;  
    this.unBindResp = null;  
    this.tmpCmd = null;  
    this.cmd = null;  
    this.serverSo = null;  
    this.so = null;  
    this.output = null;  
    this.input = null;  
    this.unErr = true;  
    //this.closeSocketFlag = false;  
    unioncomLog.info("Memory***==="  
    + java.lang.Runtime.getRuntime().freeMemory());  
    }  
    public synchronized void requireStop() {  
    this.unInterrupt = false;  
    unioncomLog.info("Requre interrupt!!!");  
    }  
    public String convertMsgContentCoding
    (int msgCoding, byte[] msgContent) {  
    String deliverContent = null;  
    try {  
    if (msgContent != null) {  
    if (msgCoding == 8) { // 处理ucs32编码  
    deliverContent = new String(msgContent,  
    "UnicodeBigUnmarked");  
    } else if (msgCoding == 0) { // 处理ASCII编码  
    deliverContent = new String(msgContent, "ASCII");  
    } else if (msgCoding == 4) { // 处理binary编码  
    deliverContent = new String(msgContent);  
    } else if (msgCoding == 15) { // 处理GBK编码  
    deliverContent = new String(msgContent, "GBK");  
    // 处理DELIVER数据包的短信息ID  
    } else {  
    unioncomLog.error("编码格式错误!");  
    return "";  
    }  
    } else  
    return "";  
    return deliverContent;  
    } catch (UnsupportedEncodingException ex) {  
    unioncomLog.error("deal content error!" +
     ex.getMessage());  
    return "";  
    }  
    }  
    }
千锋教育
2016-08-27 · 做真实的自己 用良心做教育
千锋教育
千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育。
向TA提问
展开全部
  现编这个就是个多线程服务器,只要在client不释放连接,服务器端的run里边写while(TRUE)循环,那么就可以长期连接。   class ConnectionThread extends Thread{   Socket client;   int counter;   public ConnectionThread(Socket cl,int c){   client = cl;   counter= c;   }   @Override   public void run()   {   try{   String destIP=client.getInetAddress().toString();   int destport =client.getPort();   PrintStream outstream=new PrintStream(client.getOutputStream());   DataInputStream instream=new DataInputStream(client.getInputStream());   String inline=instream.readLine();   }//try   catch(IOException e){System.out.println(e);}   }//run
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式