基本上,服务器端每8分钟发送一条keep-alive消息,如果写入失败,它将断开客户端并关闭套接字连接。如果我的android设备处于唤醒状态,服务器关闭了连接,那么android设备上的读取操作会抛出一个异常,我会断开与服务器的连接。如果设备处于休眠状态,即使有部分唤醒锁和wifilock,它也不会读取数据,我已经放弃了,但我的实际问题是,当我的设备从睡眠中恢复(例如,如果我打开屏幕)时,我所做的是向服务器发送一条消息,以便刷新数据,但如果我的服务器已经关闭了套接字,我的写操作应该抛出一个ioexception,但由于某些原因它没有。即使是我的阻塞读取也不会抛出任何异常或返回-1。
这是我的写操作:
public boolean sendData(byte[] data)
{
boolean sent=false;
if(connectedToServer)
{
try
{
myOutputStream.write(data, 0, data.length);
sent= true;
}
catch (IOException e)
{
e.printStackTrace();
unexpectedDisconnectionFromServer();
}
}
return sent;
}
下面是我的读取操作:
public void startReadingInBackground()
{
while(connectedToServer)
{
try
{
int bytesRead=0;
if(myWifiLock!=null && !myWifiLock.isHeld())
myWifiLock.acquire();
byte val=(byte)myInputStream.read();
myWakeLock.acquire();
if(val==-1)
{
unexpectedDisconnectionFromServer();
if(myWifiLock!=null && myWifiLock.isHeld())
myWifiLock.release();
myWakeLock.release();
return;
}
bytesRead=myInputStream.read(myBuffer, 0, bufferSize);
if(bytesRead<1)
{
unexpectedDisconnectionFromServer();
if(myWifiLock!=null && myWifiLock.isHeld())
myWifiLock.release();
myWakeLock.release();
return;
}
byte[] dataArray=Arrays.copyOfRange(myBuffer,0,bytesRead);
ByteBuffer data=ByteBuffer.allocate(bytesRead+1).put(val).put(dataArray);
myParent.invokeReceiveAction(data, bytesRead + 1);
}
catch (IOException e)
{
if(!myWakeLock.isHeld())
myWakeLock.acquire();
unexpectedDisconnectionFromServer();
e.printStackTrace();
}
finally
{
if(myWifiLock!=null && myWifiLock.isHeld())
myWifiLock.release();
if(myWakeLock!=null && myWakeLock.isHeld())
myWakeLock.release();
}
}
}
我得到的输出流是这样的:
Socket mySocket = new Socket(SERVER_IP, SERVER_PORT_TCP );
myOutputStream=mySocket.getOutputStream();
1条答案
按热度按时间sqyvllje1#
你的写作会给你带来
IOException,
最终。你的错误是假设它一定会发生在断开连接后的第一次写入上。它不会,因为各种各样的原因,包括缓冲和重试。tcp必须在拒绝新的写入之前确定连接是否真的死了,而且在断开连接后的第一次写入时肯定不会这样做。