【问题标题】:Java: how to connect to different servers from a client socket on one port?Java:如何从一个端口上的客户端套接字连接到不同的服务器?
【发布时间】:2016-12-23 22:02:24
【问题描述】:

一个 TCP 连接由四个元素(可能包括协议)标识:客户端端口、客户端地址、服务器端口、服务器地址。因此,一个端口的客户端可以连接到多个不同的服务器。因为它们是不同的 TCP 连接。

这是我的演示:端口 9999 上的本地客户端连接到端口 12345 和端口 12346 上的两个本地服务器。但代码不正确。

有人可以帮我吗?请告诉我如何更正它。(不要使用 SO_REUSEPORT 或 fork)

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketTest {

    public static void main(String[] args) throws IOException {


        startServer(12345);
        startServer(12346);

        Socket socket = new Socket();
        socket.bind(new InetSocketAddress(9999));
        System.out.println("client: " + socket.getLocalSocketAddress().toString());

        startClient(socket, 12345);
        startClient(socket, 12346);
    }

    public static void startClient(Socket socket, int port) {
        (new Thread() {
            @Override
            public void run() {
                try {
                    // Problem: connect() can be called only once
                    socket.connect(new InetSocketAddress(port));
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void startServer(int port) {
        new Thread() {
            @Override
            public void run() {
                ServerSocket ss;
                try {
                    ss = new ServerSocket(port);
                    System.out.println("listen on: " + ss.getLocalSocketAddress());
                    while (true) {
                        Socket s = ss.accept();
                        System.out.println("accept from: " + s.getRemoteSocketAddress());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

【问题讨论】:

  • 为什么?你关心客户端使用什么本地端口? “代码不正确”不是问题报告。为什么 SO_REUSEADDR 不可接受?不清楚你在问什么。
  • 我只是想做一个演示来验证我的想法:可以使用一个端口上的套接字连接到 2 个不同的服务器。但是我的代码不能如我所愿。你能给我修改一下代码吗?
  • 您是否要进行多播?
  • @SergeBallesta 不,只是双向通信^_^
  • @EJP 太抱歉了!我不在乎客户端使用什么本地端口。只是尝试从一个套接字建立多个连接到不同的服务器,这可能是不切实际的。问题是如果可能的话我不知道如何实现它,我想知道除了 SO_REUSEADDR 之外是否存在任何其他方式。

标签: java sockets tcp port


【解决方案1】:

您可以将 2 个不同的套接字绑定到同一个本地端口(这就是 SO_REUSEADDR 的用途),但一个套接字只能连接到一个目标。

如果您想发送一条消息,并且希望该消息被两台服务器接收,那么您需要多播。多播只能使用 UDP(而非 TCP)和 IANA 未列为 reserved 的特殊多播地址之一(224.0.0.0 到 239.255.255.255)。

【讨论】:

  • 为什么“一个socket只能连接一个destination”?一个connection包括socket(192.168.1.101:9999)和destination one(192.168.1.101:12345);另一个连接包括套接字(192.168.1.101:9999)和目标连接(192.168.1.101:12346)。两个连接是不同的。给定一个套接字可以连接到多个目的地,单个套接字可以告诉这些连接,向服务器发送不同的消息,接收服务器发送的消息,没有问题。为什么一个套接字只能连接到一个目的地?为什么存在这个限制?
  • @Qoobee:您混淆了地址(IP+端口)和套接字。套接字是允许您操作两个地址之间的交换 的句柄。 TCP 连接是您通过套接字操作的两个地址(src 和 dst IP+端口)之间的长期连接。为什么会这样?因为它是在 BSD4 中实现的方式...
猜你喜欢
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 2015-07-19
  • 2017-02-25
相关资源
最近更新 更多