Socket.sendUrgentData()使用踩雷

1 篇文章 0 订阅
1 篇文章 0 订阅

Android使用tcp连接进行通信时,因为不能及时收到服务器socket断开状态,只能通过定时发送心跳方式维持socket稳定连接,但是考虑服务器性能问题,并发上去心跳包间隔又不能太长。所以笔者以前经常使用Socket.sendUrgentData()方法进行网络连接测试,socket.sendUrgentData(0xff)方法用于向服务端发送紧急数据包,如果服务端Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的。

Window系统 Socket编程发送心跳排坑记录(socket.sendUrgentData)_等待蜗牛蜕变的博客-CSDN博客

直到在一个项目中遇到一个奇葩现象,目标服务器是远程局域网,服务器通过公网固定IP端口映射方式访问。采用如下方式连接后,socket怎么连接都正常。但是发任何数据,服务器没反应。同时Windows客户端却可以正常访问。通过抓包发现Tcp发送的有效数据包数据Data永远只有一个字节 00,说明数据压根没法出去。排查注释掉Socket.sendUrgentData()方法后才正常。此前众多项目都使用都正常,也不是服务器问题,各项目服务器程序都一样,推测可能是端口映射或防火墙配置不同,无法深究。

 

Android 抓包工具TcpDump使用方式如下(需root)

https://www.jb51.net/article/60940.htmicon-default.png?t=L892https://www.jb51.net/article/60940.htmAndroid常用抓包工具之TcpDump - 听云APM - 博客园➠更多技术干货请戳:听云博客 做为一个测试人员,工作中经常会用到数据抓包工具来进行数据分析和验证,下面就简单介绍一下工作中常用的抓包工具。 TcpDump抓包 Tcpdump是一个用于截取网络分组,并https://www.cnblogs.com/TingyunAPM/p/5427796.html

 private void connect() {
        try {
            //初始化Socket  获取连接
            mSocket = new Socket();
            InetSocketAddress isa = new InetSocketAddress(mIpAddress, mPort);
            mSocket.connect(isa);
//            mSocket.sendUrgentData(0);//血泪教训  不能加这个 随锐项目外网端口映射  加这个发送数据发不出去
            LogUtils.e(TAG, "socket-info:socket绑定的本地地址-" + mSocket.getLocalAddress());
            LogUtils.e(TAG, "socket-info:socket绑定的本地端口-" + mSocket.getLocalPort());
            LogUtils.e(TAG, "socket-info:Socket连接地址-" + mSocket.getRemoteSocketAddress());
            LogUtils.e(TAG, "socket-info:Socket上输入的缓冲区大小-" + mSocket.getSendBufferSize());
            LogUtils.e(TAG, "socket-info:Socket是否开启检测-" + mSocket.getKeepAlive());
            LogUtils.e(TAG, "socket-info:Socket是否开启NoDelay算法-" + mSocket.getTcpNoDelay());

            //初始化输入输出流
            bis = mSocket.getInputStream();
            bos = mSocket.getOutputStream();

            //启动读取服务器数据线程
            mReadThread = new ReadThread();
            mReadThread.start();
            onConnected();
        } catch (Exception e) {
            MyToast("服务器连接失败");
            e.printStackTrace();
            LogUtils.d(TAG, "socket连接失败:" + e.toString());
            if (mHandler != null) {
                mHandler.postDelayed(() -> {
                    if (mExecutorService != null && !mExecutorService.isShutdown()) {
                        mExecutorService.execute(connectRunnable);
                    }
                }, 3000);
            }
        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值