我需要与服务器建立“稳定”连接。
客户端每隔5(10,N)秒尝试连接一次服务器。
成功连接后,客户端会从服务器接收数据。
如果服务中断(例如服务器关闭),请转到步骤#1。
我如何测试:
我启动服务器
我启动客户端(以确保客户端从服务器获取数据)
我停止了服务器
我等待大约200次客户端尝试连接到服务器。
我重新启动服务器。
服务器发送数据,但客户端无法获取数据。
socket.connect(...)
是成功的,但是
socket.getInputStream().read(byte[])
不是Thread
上的input.read(..)
块。
如果我取消注释这一行:
//socket.setSoTimeout(500);
然后input.read(..)
会抛出TimeoutException
。
但是服务器从客户端接收数据。
我哪里错了? 感谢。
部分客户端代码:
private void initSocket() {
try {
if (socket == null || socket.isClosed() == true
|| socket.isConnected() == false) {
socket = new Socket();
// socket.setSoTimeout(500);
InetSocketAddress socketAddress = new InetSocketAddress("192.168.1.3"
, 12344);
notifyDataListener(4);
socket.connect(socketAddress, 500);
notifyDataListener(5);
}
} catch (Throwable t) {
System.err.println(t);
}
}
private void closeSocket() {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (Throwable t) {
System.err.println(t);
}
}
private byte[] buffer = new byte[1024];
public void run() {
while (isActive) {
try {
notifyDataListener(1);
initSocket();
InputStream input = socket.getInputStream();
int length = input.read(buffer);
if (length < 0) {
throw new EOFException("Was got -1");
}
notifyDataListener(2);
} catch (Throwable t) {
closeSocket();
notifyDataListener(3);
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
}
}
}
在J2SE上,相同的代码工作正常。许多错误尝试后连接修复。 看起来Android有限制套接字(FileDescriptior?),接受它们,但不会发布。
答案 0 :(得分:0)
你的文件描述符可能用完了,我确定android的限制比典型的桌面配置要低得多,但具体的值会有所不同。
根据您对此进行编码的方式,套接字将一直挂起,直到其垃圾被收集,另外在某些平台上,操作系统级别的套接字不会立即关闭,而是会挂起一段时间来清理任何挂起的数据。
您应该做的第一件事是将socket.close()
代码移动到finally {}
语句,这将立即释放套接字,而不是等待垃圾回收。