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

在使用TCP Socket进行颜色控制时遇到问题,包括:1) 后续操作产生延迟,灯色改变延迟超过1分钟;2) 连击操作导致程序崩溃;3) 程序崩溃后灯快速变化。已提供部分关键代码,涉及并发队列、Socket连接和数据发送。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在线等待。
我的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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值