我在2個線程中使用一個SocketChannel,一個線程用於發送數據,另一個線程用於接收數據。Java NIO TCP超時問題
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(ip,port));
socketChannel.configureBlocking(false);
線程1:使用上述的SocketChannel寫入數據
線程2:使用相同的SocketChannel讀取
我不使用任何選擇器與所述的SocketChannel如我所需的數據寫入和讀取異步(使用2個不同的線程)
問題:當連接丟失時,socketchannel.write()和socketchannel.read()操作不會引發任何錯誤。它只是阻止操作。
我需要檢測連接丟失。
我試過在線程2中使用心跳方法,但因爲讀取操作剛好阻塞,所以此方法無法工作。有沒有其他方法可以在不使用新線程中的心跳的情況下檢測連接丟失?
如果存在連接丟失,寫入/讀取時是否可能拋出錯誤?
在此先感謝。
編輯:
主題1:
public void run() {
socketChannel = SendAndReceivePacketUtil.createConnection(ip, port);
socketChannel.configureBlocking(false);
RecTask task = new RecTask(socketChannel);
Thread recThread = new Thread(task);
recThread.start();
while(true)
{
byte[] data= getDataFromQueue(ip);
if(data!= null) {
//print(new String(data));
sendPacket(data, socketChannel);
}
}
}
線程2:(RecTask)
public void run() {
while(true) {
byte[] data = receivePacket(socketChannel);
//print(new String(data));
}
}
兩個線程1 & 2具有的try-catch-finally塊。最後關閉套接字通道。
了sendpacket:
int dataSent = 0;
while (dataSent < data.length) {
long n = socketChannel.write(buf);
if (n < 0) {
throw new Exception();
}
dataSent += (int) n;
}
receivePacket:
int dataRec = 0;
byte[] data = new byte[length];
ByteBuffer buffer = ByteBuffer.wrap(data);
while (dataRec < length) {
long n = socketChannel.read(buffer);
if (n < 0) {
throw new Exception();
}
dataRec += (int) n;
}
return data;
我發送和連續接收數據。但是一旦連接丟失,就不會打印,代碼就會卡住。它是一個android wifi直接應用程序。對於連接丟失情況,我只需關閉wifi模塊。
我已經用所需的代碼更新了問題。雖然我處於非阻塞模式,但在連接丟失時仍無法打印任何內容。此外代碼不會進入catch/finally塊,這就是爲什麼我假設代碼等待讀/寫操作。 –
@Pulkit顯然,您的讀取和您的寫入都返回零,這會導致無限循環。這就是爲什麼你需要'select()''不使用'select()'來編寫非阻塞循環,這只是一個糟糕的技術,並且會浪費CPU的時間。 – EJP
使用select可以使讀和寫異步嗎?另外,如果我將socketChannel.configureBloacking()更改爲true,那麼應該解決問題,對吧? –