Настройка исходного порта на сокете Java? - PullRequest
11 голосов
/ 02 декабря 2009

Я очень новичок в программировании сокетов:

Можно ли явно указать исходный порт на сокете Java?

Я работаю над клиент-серверным приложением, в котором клиенты потенциально могут прослушивать ответы с сервера на нескольких портах. Было бы хорошо, если бы я мог установить этот порт ответа на стороне клиента при инициализации Socket, чтобы сервер мог определить, какой порт отвечать на другой стороне.

Ответы [ 5 ]

6 голосов
/ 02 декабря 2009

Обычно это выглядит так:

Сначала Сервер открывает ServerSocket на хорошо известном порту и ожидает ввода.

Тем временем Клиент открывает (клиентский) сокет с именем хоста сервера и этим хорошо известным адресом порта. Он отправляет сообщение запроса на сервер для инициализации сеанса связи.

Сервер получает сообщение, порождает рабочий поток, который открывает другой ServerSocket на другом порту, и сервер отправляет ответ, в котором сообщает клиенту этот номер порта.

Теперь клиент закрывает фактическое соединение и создает новый сокет, теперь с номером порта, который ему только что сказали.

Таким образом, сервер может обрабатывать более одного клиента одновременно, потому что каждый клиент получает свое индивидуальное «соединение» (порт).

4 голосов
/ 02 декабря 2009

Да, используйте метод <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html#bind%28java.net.SocketAddress%29" rel="nofollow noreferrer"><strike>bind()</strike></a>. Это отражает функцию <a href="http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29" rel="nofollow noreferrer">bind()</a>, доступную в большинстве реализаций сокетов уровня C. Обратите внимание, что вы не всегда можете свободно выбирать, какой порт использовать, в некоторых системах некоторые диапазоны зарезервированы и считаются недоступными для пользовательских приложений.

3 голосов
/ 27 августа 2010

При использовании дейтаграммы, адрес источника и порт задаются сокетом при отправке дейтаграммы.

InetAddress sourceAddr = InetAddress.getLocalHost();
DatagramSocket sock = new DatagramSocket(sourcePort, sourceAddr);
DatagramPacket msg = new DatagramPacket(mbuf, mbuf.length, dstIP, dstPort);

sock.send(msg); // sent from sourcePort to dstPort

sourceAddr немного избыточен в этом примере, new DatagramSocket(sourcePort) будет привязываться к предпочтительному адресу с лучшим выбором, но если вам нужно указать IP-адрес источника помимо порта, вот как.

Для сокетов обоих типов при использовании bind(new InetSocketAddress(port)) будет выбран соответствующий адрес локального источника и указанный порт, а порт 0 также выберет соответствующий локальный порт.

Все извлекаются с getLocalAddress() и getLocalPort().

1 голос
/ 02 декабря 2009

Вы можете использовать этот вызов для создания сокета,

public Socket(InetAddress address,
              int port,
              InetAddress localAddr,
              int localPort)
       throws IOException

Обычно это делается для UDP и не рекомендуется для TCP-соединений. Если вы делаете это для TCP на обоих концах, у вас может быть только одно TCP-соединение. Если вы создадите еще один, сокетный слой будет сбит с толку, и вы в конечном итоге потеряете все свои соединения.

Для TCP обычной практикой является ответ в том же соединении. Если вам нужно ответить в другом соединении, используйте также заранее определенные порты на клиенте.

0 голосов
/ 02 декабря 2009

Во-первых, я настоятельно рекомендую вам использовать Java NIO.

DatagramChannel udpchannel = DatagramChannel.open();
DatagramSocket udpsocket = udpchannel.socket();
SocketAddress sa = new InetSocketAddress(BIND_ADDRESS, BIND_PORT);
udpsocket.bind(sa);

Во-вторых, используя привязку к адресу сокета, вы также сможете определить, к какому сетевому адресу вы будете подключены. Это означает, что если вы установите BIND_ADDRESS на «0.0.0.0», вы сможете прослушивать все сетевые карты, подключенные к вашему серверу; но если вы установите для BIND_ADDRESS значение, например, «10.190.0.1», вы будете получать запросы только на таком адресе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...