2015-10-10 3 views
-1

У меня возникли проблемы с пониманием того, почему прием вызова для UDP-соединения, похоже, не блокирует. Любая помощь будет оценена по достоинству.Java DatagramSocket receive() call not blocking/not throwing SocketTimeoutException

В принципе, полный код должен считывать и отправлять сегменты байта файла через UDP на другой запущенный процесс, прослушивающий на определенном порту, так что , что процесс может затем восстановить (копию) файла. В этом случае, однако, такого слушателя пока нет. ниже код включает только разделы, которые я думаю, беда в.

import java.util.*; 
import java.io.*; 
import java.nio.*; 
import java.net.*; 

//... setup code ... 

Datagram connection = null; 
try { 
    address = new InetSocketAddress(hostName, portNum); //Assume the hostName and portNum are valid (i.e. localhost, port 8250) 
    connection = new DatagramSocket(address); 
    connection.setSoTimeout(100); //This doesn't seem to work, even if I set this to 1000000 
} catch (IOException e) { 
    //Quit 
    System.out.println(ERROR_UNABLE_TO_CONNECT); 
    return; 
} 

//... read contents from sourceFile and create a DatagramPacket for sending first few bytes ... 

boolean received = false; 
byte[] ackPacketBuffer = new byte[1000]; 
DatagramPacket ackPacket = new DatagramPacket(ackPacketBuffer, ackPacketBuffer.length); 
while(!received) { 
    try { 
     connection.send(fileNamePacket); //fileNamePacket can be treated as the packet to be sent 
     connection.receive(ackPacket); //From my understanding, this should block at least for the set time, before throwing SocketTimeoutException 

     //... do some checks on the ackPacket, set received flag to be true if successful so that loop is broken... 

    } catch (SocketTimeoutException e) { 
     //Packet potentially lost, resend 
     System.out.println(ERROR_TIMEOUT); 
     continue; 
    } catch (IOException e) { 
     System.out.println(ERROR_SOCKET_WRITE); 
     continue; 
    } 
} 

Из того, что я думаю, что должно произойти, данный сценарий, для которого нет никакого слушателя для указанного порта, вызов получить должен блок, ожидающий подтверждения, которое никогда не должно появляться, до истечения времени ожидания, в этом случае следует исключить исключение SocketTimeoutException, активируя соответствующий блок catch и вызывая появление сообщения об ошибке на экране.

К сожалению, я ничего не получаю - размещение заявления печати после вызова connection.receive() показывает бесконечный цикл. Нужно ожидать бесконечного цикла, но почему я не получаю исключение SocketTimeoutException?

Другие вопросы, которые я столкнулся до сих пор:

  1. setSotimeout on a datagram socket
  2. DatagramSocket not throwing SocketTimeout - Java
  3. Adding timeout to DatagramSocket - receive()
+0

Итак, вы получаете что-то. Какие? – EJP

+0

По праву я должен получать ACK-пакет из процесса, прослушивающего этот порт, что указывает, что он успешно получил первый пакет. Но поскольку на данный момент такого процесса нет, я думаю, что я должен хотя бы получить исключение SocketTimeoutException. Но связанная распечатка с SocketTimeoutException никогда не печатается, и я не понимаю почему. –

+0

Дело в том, что вы * * что-то получаете *. Повторяю. Какие? Отслеживание полученного пакета. Вы можете получить сюрприз. – EJP

ответ

1

я решил проблему. Раньше у DatagramSocket был InetSocketAddress. Теперь, вместо передачи в InetSocketAddress конструктору DatagramSocket, я не прохожу ни в чем:

connection = new DatagramSocket(); 

В DatagramPackets посланного через DatagramSocket будет один, который имеет InetSocketAddress вместо.

+0

Это приводит к тому, что 'DatagramSocket' привязан к этому IP-адресу и поэтому принимает только пакеты, адресованные именно этому IP-адресу (по модулю слабой модели системы, если это применимо). Если вы его не поставляете или не поставляете «null», он связывается с 0.0.0.0, что означает «получать с любого локального IP-адреса». – EJP

+0

Обратите внимание, что в вашем вопросе конкретно говорится: «Предположим, что имя хоста и portNum являются действительными». Они не были. – EJP

+0

Имя хоста и portNum (в объекте InetSocketAddress) работает, когда отправлено в DatagramPacket, оно не работает при отправке в DatagramSocket. –

Смежные вопросы