前几天用Mina2.0创建了一个tcp c/s架构的程序,可以实现客户端与服务器的长连接,方便向客户端反向推送一些消息.
经过一天晚上的压力测试,服务器端表现非常的完美,客户端的上线,正常下线与不正常下线都能立即检测的到,踢掉客户端功能也运行正常。问题就在于我的Pad端,Android5.1系统,x86架构,昂达的Pad,出现了问题。一夜之后wifi就无法连接了,用adb勉强连上Pad logcat一下发现system_process进程一直在尝试重新连接已经保存的无线,可是最终都会报出一个错误:无法得到文件描述符。于是我使用adb shell 连进Adnroid内核shell,lsof一下,发现打印出来的列表n多,当时我的内心是崩溃的,不过心里也有点小高兴,因为我找到了问题的所在,有可能= =。。
问题出在我的代码上。
修改之前的代码:
package core;
import java.net.InetSocketAddress;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import base.Global;
public class TcpClient extends Thread{
private final static boolean DEBUG = true;
private IoConnector conn = null;
private IoSession session = null;
private IoHandler handler = null;
private ClientStatus clientStatus = ClientStatus.IDLE;
private InetSocketAddress inetAddress = null;
public TcpClient() {
// init mina
conn = new NioSocketConnector();
conn.setConnectTimeoutMillis(1000 * 60);
conn.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MessageCodecFactory()));
/** 主角登场 */
KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory, IdleStatus.BOTH_IDLE);
/** 是否回发 */
heartBeat.setForwardEvent(true);
/** 发送频率 */
heartBeat.setRequestInterval(15);
// connector.getSessionConfig().setKeepAlive(true);
conn.getFilterChain().addLast("heartbeat", heartBeat);
if(null == handler) {
handler = new DefaultClientHandler();
}
conn.setHandler(handler);
start();
}
public IoSession getSession() {
return session;
}
@Override
public void run() {
for(;;) {
try {
switch (clientStatus) {
case IDLE:
break;
case RUNNING:
if(DEBUG) {
System.out.println("Connecting...");
}
// conn = new NioSocketConnector();
ConnectFuture future = conn.connect(inetAddress);// ��������
future.awaitUninterruptibly();// �ȴ&