2013-09-10 4 views
2

Я создаю программу, которая будет подключать каждый компьютер в моей локальной сети к моему компьютеру через DatagramSocket и DatagramPacket (другими словами, я буду сервером, а остальные будут клиентами). Я провел некоторое исследование и прочитал документацию, и выяснил, как это работает, и я действительно смог отправлять и получать данные по сети. У меня было два варианта метода отправки данных в классе клиента, который, как я думал, был эквивалентным, но, похоже, нет. Первый (Client1):Почему разные конструкторы DatagramSocket ведут себя так разные? (BindException)

DatagramSocket socket = null; 
DatagramPacket packet = null; 

try 
{ 
    byte[] data= "test".getBytes(); 
    packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325); 
    socket = new DatagramSocket(); 
    socket.send(packet); 
} 
catch (Exception ex) 
{ 
    ... 
} 

И второй один (Client2):

DatagramSocket socket = null; 
DatagramPacket packet = null; 

try 
{ 
    byte[] data= "test".getBytes(); 
    packet = new DatagramPacket(data, data.length); 
    socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26")); 
    socket.send(packet); 
} 
catch (Exception ex) 
{ 
    ... 
} 

Эти два варианта, когда я делал тесты, отправляющие данные и от моего собственного компьютера. Мой IP-адрес - 192.168.0.26. С первым я не имел никаких проблем, но второй из них выдает два вида исключений. Я могу подтвердить, что Client1 работает работает следующий код в компьютере в то же время

(сервер)

byte data[] = null; 
try 
{ 
    data= new byte[1000]; 
    socket = new DatagramSocket(325); 
    packet = new DatagramPacket(datos, datos.length); 
    socket.receive(packet); 
    System.out.println(datos); 
} 
catch (Exception ex) 
{ 
    ... 
} 

Если я запускаю сервер первым, а затем вариант Client1, он на самом деле recieves данные. Когда я запускаю Client1 сначала, а затем Сервер, явно не получаю никаких данных, но не получаю никаких исключений. Реальная проблема (и актуальный вопрос, извините за столько, может быть, бесполезную информацию) - с Client2. Если это побежал перед тем сервером, я получаю NullPointerException:

java.lang.NullPointerException: null address || null buffer 
at java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:115) 
at java.net.DatagramSocket.send(DatagramSocket.java:676) 

генерируется, когда метод отправки() вызывается. Я знаю, может быть, я должен проигнорировать это; даже подумал, что я немного новичок с Socket, кажется, неправильно отправлять данные, если вы знаете, что никто этого не получит. В другой стороны, когда сервер работает, а затем CLIENT2, я получаю BindException:

java.net.BindException: Address already in use: Cannot bind 
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method) 
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:65) 
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:95) 
at java.net.DatagramSocket.bind(DatagramSocket.java:376) 
at java.net.DatagramSocket.<init>(DatagramSocket.java:231) 
at java.net.DatagramSocket.<init>(DatagramSocket.java:284) 

от линии, когда сокет инициализируется. Благодаря тому, что Client1 работает, я буду использовать его; но мне очень хотелось бы знать, почему это работает, но Client2 этого не делает. Я читал на другом форуме здесь об этом BindException, и я понял, что это было вызвано, когда вы пытаетесь использовать один порт, который уже используется, но в этом смысле Client1 тоже должен потерпеть неудачу. Может ли кто-нибудь объяснить мне разницу между Client1 и Client2?

ответ

2

Вы связываетесь с одним и тем же портом, если вы используете его на одном компьютере/адресе, вам необходимо привязать его к различным портам.

Как на сервере:

socket = new DatagramSocket(325); //server binds its UDP/IP socket to port 325 

На клиенте 2:

socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26")); 

вы привязки к одному порту на той же машине/адрес, что «сервер» использует

На клиента 1:

packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325); 
//you are specifying the destination address and port the packet should be sent. 
socket = new DatagramSocket(); 
//but in the DatagramSocket contructor you don't pass any address or port to bind to, so it will use an available port, not 325 as it is in use by the server. 

Как вы сказали, вы недавно подключились к сети, имейте в виду, что это сокеты UDP/IP, есть TCP/IP и другие. UDP/IP не является соединением, ориентированным по спецификации, и не гарантирует доставку пакета.

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