在线等待,求高手,socket发送延迟问题

原创 2017年01月03日 05:36:15
在线等待。
我的app可以按取颜色(色盘与固定颜色的button),使用tcp socket传输,让灯可以根据按的颜色做改变。
目前碰到的问题是:
1. 前面动作都可以正常执行,但按取到后面时就会产生延迟的问题发生。颜色还是可按取,但灯不会变色,但时间超过很久(超过1分钟或更久)灯就会照刚才按取的颜色依序变色。
2. 按取的动作快一点(ex:连击),程序就会整个崩溃。
3. 程序崩溃后,灯就会以非常快的速度改变,刚才不会变灯色之后所按取的颜色。

我会发送类似这样的讯息:
getActivity().startService(new Intent(getActivity(), NotificationService.class)
           .setAction(NotificationService.ACTION_SENT)
           .putExtra(NotificationService.EXTRA_PARAM_TARGET_ADDR, "192.168.1.1")
           .putExtra(NotificationService.EXTRA_PARAM_TARGET_PORT, 1281)
           .putExtra(NotificationService.EXTRA_PARAM_TARGET_DATA, cmd));


这是我写的程序

public class NotificationService extends Service {

    private static final String DATAGRAM_TARGET_ADDR_DEF = "192.168.168.254";
    private static final int    DATAGRAM_TARGET_PORT_DEF = 12098;

    public static final String ACTION_SENT = "ACTION_SENT";
    public static final String EXTRA_PARAM_TARGET_ADDR = "EXTRA_PARAM_TARGET_ADDR";
    public static final String EXTRA_PARAM_TARGET_PORT = "EXTRA_PARAM_TARGET_PORT";
    public static final String EXTRA_PARAM_TARGET_DATA = "EXTRA_PARAM_TARGET_DATA";

    public static final String ACTION_DNS = "ACTION_DNS";
    public static final String EXTRA_PARAM_LOOKUP_ADDR = "EXTRA_PARAM_LOOKUP_ADDR";

    //private static Context ctx = null;

    private static ConcurrentLinkedQueue<Map<String, Object>> mQueueSend = new ConcurrentLinkedQueue<>();
    //private static ConcurrentLinkedQueue<Map<String, Object>> queueRecv = new ConcurrentLinkedQueue<>();

    private static Thread mThreadConn = null;
    private static Thread mThreadSend = null;
    private static Thread threadRecv = null;

    private static final Lock mMutexSocket = new ReentrantLock(true);
    private static final Lock mMutexTxData = new ReentrantLock(true);
    private static final Lock mMutexRxData = new ReentrantLock();

   
    private static InetSocketAddress address = new InetSocketAddress(DATAGRAM_TARGET_ADDR_DEF, DATAGRAM_TARGET_PORT_DEF);

    private static Socket socket = null;
    private static OutputStream output = null;
    private static InputStream input = null;

    private static BufferedWriter writer = null;
    private static BufferedReader reader = null;


    private static final Runnable mRunnableConnDev = new Runnable() {

        @Override
        public void run() {

            try {

                Log.d(this.getClass().getSimpleName(), "5. new Socket ---> TRY!");
                mMutexSocket.lock();
                //socket = new Socket("192.168.168.254", 12098);
                socket = new Socket(DATAGRAM_TARGET_ADDR_DEF, DATAGRAM_TARGET_PORT_DEF);
                Log.d(this.getClass().getSimpleName(), "7. new Socket ---> OK!");
                writer = new BufferedWriter(new OutputStreamWriter(
                        socket.getOutputStream()));
                reader = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));

            } catch ( SocketException e ) {
                Log.d(this.getClass().getSimpleName(), "new Socket ---> NG!");
            } catch (UnknownHostException e) {
                e.printStackTrace();
                Log.d(this.getClass().getSimpleName(), "new Socket ---> Exception!");
            } catch (IOException e) {
                e.printStackTrace();
                Log.d(this.getClass().getSimpleName(), "new Socket ---> Exception!");
            } finally {
                mMutexSocket.unlock();
            }
            /* do some delays */
            try {
                mThreadConn.sleep(100);
                Log.i(this.getClass().getSimpleName(), "11. Socket delay some time");
            } catch ( InterruptedException e ) {
            }
        }
    };

    private static final Runnable btRunnableSendData = new Runnable() {

        @Override
        public void run() {
            Map<String, Object> map = null;
            while ( true ) {

                mMutexTxData.lock();
                if ( false == mQueueSend.isEmpty() ) {           
                    map = mQueueSend.peek(); 
                    Log.i(this.getClass().getSimpleName(),"get mQueueSend head:"+map);
                    mMutexTxData.unlock();
                   
                    if ( false == map.containsKey(EXTRA_PARAM_TARGET_DATA) ) continue;
                    Log.d(this.getClass().getSimpleName(), "6. TCP:have R data");

                    mMutexSocket.lock();
                    
                    if ( false == address.equals(socket.getRemoteSocketAddress())) {
                        mMutexSocket.unlock();
                        Log.i(this.getClass().getSimpleName(), "1010101010101010101010");

                        /* do some delays */
                        try {
                            mThreadSend.sleep(100);
                            Log.i(this.getClass().getSimpleName(), "12. send delay some time");
                        } catch ( InterruptedException e ) {
                        }
                        continue;
                    }
                    mMutexSocket.unlock();
                    try {
                        mMutexSocket.lock();
                        final byte[] bytes = map.get(EXTRA_PARAM_TARGET_DATA).toString().getBytes();   
                        String cmd = new String(bytes, StandardCharsets.UTF_8);
                        writer.write(cmd + "\n");
                        writer.flush();
                        mThreadSend.sleep(100);
                    } catch ( IOException e ) {
                    } catch ( InterruptedException e ) {
                    } finally {
                        mMutexSocket.unlock();
                    }
                    mQueueSend.poll();
                    continue;
                }
                mMutexTxData.unlock();
            }
        }
    };

    private static final Runnable btRunnableRecvData = new Runnable() {

        @Override
        public void run() {
            while ( true ) {
            }
        }
    };

    public static final BroadcastReceiver btStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        }
    };

    @Override
    public void onCreate() {
        Log.i("NotificationService", "socket:onCreate~~~");
        Log.i(this.getClass().getSimpleName(), "in thread number:"+Thread.activeCount());

        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(this.getClass().getSimpleName(), "1. socket:onStartCommand~~~");

        if ( null != intent && null != intent.getAction() ) {
            Map<String, Object> map = new HashMap<>();
            if ( ACTION_SENT.equals(intent.getAction()) ) {
                if ( true == intent.hasExtra(EXTRA_PARAM_TARGET_ADDR) &&
                        true == intent.hasExtra(EXTRA_PARAM_TARGET_PORT) &&
                        true == intent.hasExtra(EXTRA_PARAM_TARGET_DATA) ) {

                    /* prepare target address & port */
                    mMutexSocket.lock();
                    address = new InetSocketAddress(
                            intent.getStringExtra(EXTRA_PARAM_TARGET_ADDR),
                            intent.getIntExtra(EXTRA_PARAM_TARGET_PORT, DATAGRAM_TARGET_PORT_DEF));
                    mMutexSocket.unlock();

                    /* start thread to connect */
                    //if ( null == mThreadConn || Thread.State.TERMINATED.equals(mThreadConn.getState()) ) {
                        mThreadConn = new Thread(mRunnableConnDev);
                        mThreadConn.start();
                    //}

                    /* prepare tx data */
                    map.put(EXTRA_PARAM_TARGET_ADDR, intent.getStringExtra(EXTRA_PARAM_TARGET_ADDR));
                    map.put(EXTRA_PARAM_TARGET_PORT, intent.getIntExtra(EXTRA_PARAM_TARGET_PORT, DATAGRAM_TARGET_PORT_DEF));
                    map.put(EXTRA_PARAM_TARGET_DATA, intent.getStringExtra(EXTRA_PARAM_TARGET_DATA));

                    /* put tx data into queue */
                    mMutexTxData.lock();
                    mQueueSend.add(map);
                    mMutexTxData.unlock();
                    
                    /* start thread to transfer */
                    //if ( null == mThreadSend || Thread.State.TERMINATED.equals(mThreadSend.getState()) ) {
                        mThreadSend = new Thread(btRunnableSendData);
                        Log.i(this.getClass().getSimpleName(),"new senddata thread");
                        mThreadSend.start();
                        Log.i(this.getClass().getSimpleName(),"thread start....");
                        Log.i(this.getClass().getSimpleName(),"first Send Data:"+data);
                    //}
                }
            }
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        //Log.i("NotificationService", "onDestroy~~~");

        //unregisterReceiver(btStateReceiver);
        if (socket != null)
        {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

TcpSocket发送延时,Nagle算法

1. Nagle算法: 是为了减少广域网的小分组数目,从而减小网络拥塞的出现; 该算法要求一个tcp连接上最多只能有一个未被确认的未完成的小分组,在该分组ack到达之前不能发送其他的小分组,tcp...
  • gch293
  • gch293
  • 2016年12月27日 12:30
  • 640

TCP协议下Socket接收比较慢点原因

https://support.microsoft.com/zh-cn/kb/214397设计问题-通过使用 Winsock TCP 发送较小的数据段  电子邮件  打印 重要说明:本文是由...
  • thinbug
  • thinbug
  • 2016年05月03日 13:55
  • 5818

socket的延时技巧

      TCP/IP   Winsock编程要点           蒋勇           2002.5.23                     ...

DELPHI高性能大容量SOCKET并发(九):稳定性问题解决

IOCP接收缓存导致的内存错乱 在用IOCP控件写了一个ERP服务器后,服务器会发生运行3天后,出现莫名的内存错误,用FastMM检测,是本没有内存错误的地方,而且内存错误出现的地方也不固定。这是一...

socket为send和recv设置超时时间

linux和windows下用setsockopt设置SO_SNDTIMEO,SO_RCVTIMEO的参数的一点区别   UDP的socket在某些情况:如对方关闭时,本地可能sen...
  • aa2650
  • aa2650
  • 2013年12月19日 16:05
  • 17446

Delphi TclientSocket和TserverSocket用法(1)

Delphi,网络通信,TserverSocket,TclientSocket 现在将本人总结出来的TServerSocket和TClientSocket两个组件的基本用法写出来,希望与您分享。...

Delphi Socket 实现编程(3)

1. Socket 定义: 网络上两个程序为了相互通讯运行,构成服务端客户端结构,连接的每一端可称为一个Socket (或者套接字)。 客户程序可以向服务端Socket 发送请求,服务端收到后处...

嵌入式 setsockopt设置socket—attr达到send立即发送不延时MTU

setsockopt 编辑 setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。 ...
  • skdkjxy
  • skdkjxy
  • 2014年04月10日 13:52
  • 1528

网络编程感想(一)基于socket传输延迟问题

最近在编写一个象棋对弈平台,在编译过程中感悟颇多,在今天的编写过程中,写了一些代码,突然遇到问题就去调试,本来在异步传输的情况下,调试就有点麻烦,今天遇到的问题的是我在调试过程中,结果是和我预期的一样...

使用ItemDecoration 为 RecyclerView设置可 推动的 悬浮导航栏效果

开始逐渐领略到ItemDecoration的美~ 今天让我 使用 ItemDecoration 来完成 可推动的悬浮导航栏的效果,最终实现的效果如下图: 具体实现步骤如下...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在线等待,求高手,socket发送延迟问题
举报原因:
原因补充:

(最多只允许输入30个字)