2015-11-25 7 views
0

Я работаю над клиентом UDP для связи с сервером, на котором у меня нет контроля. Часть требования к общению с этим сервером заключается в том, что я должен предоставить номер порта UDP [как часть сообщения] для сервера для его ответа.Нужна помощь в получении моего клиентского приложения Java UDP

У меня есть несколько классов в моем приложении, которые требуют DatagramSocket, представляющим различные запросы на этот сервер, поэтому я создал статический класс:

package mypackage; 

import java.net.DatagramSocket; 
import java.net.InetSocketAddress; 
import java.net.SocketException; 

public class DatagramSocketGrabber { 

    public DatagramSocketGrabber(){} 

    public static DatagramSocket getSocket() throws SocketException { 
     DatagramSocket newSocket = new DatagramSocket(); 
     InetSocketAddress newSocketAddress = new InetSocketAddress(15346); 
     newSocket.bind(newSocketAddress); 
     return newSocket; 
    } 
} 

В моем основном() классе, я захватывая этот сокет соединение и использовать его на протяжении всей моей заявки:

package mypackage; 

import java.net.DatagramSocket; 
import java.net.SocketException; 

public class MyApp { 
    public static void main(String[] args){ 
     DatagramSocket mySocket = null; 

     try { 
      mySocket = DatagramSocketGrabber.getSocket(); 
     } catch(SocketException se){ 
      System.out.println(se); 
     } 

     DSClass01 class01 = new DSClass01(mySocket); 
     DSClass02 class02 = new DSClass02(mySocket); 
     DSClass03 class03 = new DSClass03(mySocket); 

     mySocket.close(); 
    } 
} 

Однако всякий раз, когда я запускаю мое приложение, я всегда получаю ошибку:

java.net.SocketException: already bound

НУЖНО ЗНАТЬ:

UDP-сервер на моей машине (локальный), но это компилируется приложение, поэтому я не могу изучить его код. Да, это из надежного источника.

Нет проблем с брандмауэром или сетью, поскольку он представляет собой автономный компьютер со всем широким открытым доступом.

Прежде чем создать статический класс DatagramSocketGrabber, я создал новый DatagramSocket во всех своих классах сообщений, и сервер смог успешно получить мои сообщения.

Однако причина, по которой я создал статический класс, состоит в том, что я не получал никаких ответов, и я решил, что это связано с тем, что я не привязывал мой сокет к «фиксированному» порту приема. Чтобы сделать это и иметь возможность использовать этот связанный сокет во всех моих классах сообщений, я решил, что мне нужно создать класс создания DatagramSocket, чтобы иметь один связанный сокет, который я мог бы пройти.

+0

Кажется, вы пытаетесь связать порт 15346 несколько раз – malinator

ответ

0

Хорошо ... Я понял. После дня поиска в Интернете я нашел this сообщение здесь, на StackOverflow. Все, что я должен был сделать изменить DatagramSocketGrabber от

DatagramSocket newSocket = new DatagramSocket(); 

в

DatagramSocket newSocket = new DatagramSocket(null); 

И все работало, как ожидалось.Объяснение заключается в следующем:

Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind later on.

Благодаря Perception за его/ее ответ!

1

Мое предположение, так как вы не разделяете код, который бросает исключение SocketException, это одно из следующего.

1) Вы вызываете DatagramSocketGrabber.getSocket(); второй раз в свою программу, следовательно, SocketException.

2) Вы оставили некоторый код, который является обязательным к тому же порту (как new InetSocketAddress(15346);)

Попробуйте искать код для сокета связывания (15346) и попытаться найти, если есть какие-либо другие DatagramSocketGrabber.getSocket(); вызова в вашем программа.

В то же время вы можете изменить свой DatagramSocketGrabber на однотонный и сохранить DatagramSocket в качестве атрибута, поэтому вы всегда можете вызывать свой синглтон вместо передачи сокета всем вашим методам.

+0

Это фантастическое предложение об использовании синглтона в качестве DatagramSocketGrabber ... спасибо! Что касается пунктов 1 и 2, это не проблема, но спасибо. – Brian

+0

Кроме того, код, бросающий исключение, является блоком «try» в методе main(), который я перечислил. – Brian