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.htmhttps://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);
}
}
}
|