【问题标题】:How do i get the port and address of client without receiving data from it first?如何在不先从客户端接收数据的情况下获取客户端的端口和地址?
【发布时间】:2021-06-22 10:33:29
【问题描述】:

我正在制作一个简单的 UDP 聊天程序,我希望服务器能够在不先从客户端接收数据的情况下向客户端发送数据。正常情况下,服务器在接收到客户端的数据时,会得到客户端的IP和端口,这样就可以和客户端通信了。

我的服务器代码:

package com.ageforce;

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

public class ChatServer {
    DatagramSocket server;
    byte[] receivedData = new byte[1024];
    Scanner scanner = new Scanner(System.in);
    byte[] sentData;
    DatagramPacket dp2 = new DatagramPacket(receivedData, receivedData.length);

    public ChatServer() throws SocketException {
        server = new DatagramSocket(7000);
    }

    public static void main(String[] args) throws SocketException {
        ChatServer cs = new ChatServer();

        Thread receiveMessage = new Thread(() -> {
            while (true) {
                try {
                    cs.server.receive(cs.dp2);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                String storedData = new String(cs.dp2.getData());
                System.out.println(storedData);
            }
        });

        Thread sendMessage = new Thread(() -> {
            while (true) {
                String sentMessage = cs.scanner.nextLine();
                cs.sentData = sentMessage.getBytes();

                // This is the area of the code where the server gets IP and port of client from the received data. I'd like this to be changed.
                InetAddress getIP = cs.dp2.getAddress();
                int port = cs.dp2.getPort();

                DatagramPacket dp3 = new DatagramPacket(cs.sentData, cs.sentData.length, getIP, port);
                try {
                    cs.server.send(dp3);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


        sendMessage.start();
        receiveMessage.start();
    }
}

可以这样做吗?非常感谢任何回复。

【问题讨论】:

    标签: java server udp


    【解决方案1】:

    如何在不先从客户端接收数据的情况下获取客户端的端口和地址?

    UDP 不提供这种可能性。它是一个无连接协议,因此服务器在收到来自客户端的消息之前甚至都不知道客户端。

    您可以想象创建某种初步的应用程序级协议,让客户端在向服务器发送任何聊天数据之前向服务器宣布自己,但这类协议并不是 UDP 本身的一部分,如果这是您想要的,那么您应该考虑改用 TCP,它确实具有在发送任何数据之前建立连接的内置概念。

    【讨论】:

      【解决方案2】:

      为了向某物发送 UDP 消息,您需要知道要将其发送到的 IP 和端口号。如何?好吧,你告诉我。

      你的协议现在的工作方式是客户端知道你的主机名(他们让他们的系统自动变成一个 IP),并且端口号在客户端应用程序中被硬编码。 服务器在收到呼叫时通过检查“发送方”IP/端口来知道将数据发送回哪个 IP 和端口。

      如果您不喜欢当前的协议,则需要找出不同的方法来回答这个问题。

      即使你找到了方法,你也会发现这大多是无用的。绝大多数最终用户故意没有所谓的可公开路由的 IP 地址。您无法通过设计联系他们。在您当前的协议中,您发回的那个 IP/端口组合根本不是真正的发送计算机。它是一些路由器,例如他们家中的路由器。该路由器看到了传出 UDP 数据包,并且暂时记住了:任何进入该端口的流量都应该流向这所房子里的那台计算机。

      缺少完全疯狂的东西,例如“打孔”(Skype 使用了一段时间,不确定它们是否仍然有效,这是一种复杂的 hack,并不总是有效,而且肯定不是你想要的 - 你可以在网上搜索该术语),您在这里无能为力。最终用户系统不是服务器,因此无法像这样访问。

      您的普通聊天应用程序将始终让客户端 ping 服务器,然后尽可能保持该连接打开。

      【讨论】:

        猜你喜欢
        • 2014-12-29
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-30
        • 2020-07-25
        • 2015-07-04
        相关资源
        最近更新 更多