UDP消息服务
UDP messaging service
我必须创建一个程序来发送和接收消息 to/from 一个远程 IP 地址。所以基本上它应该模拟消息服务。在程序中,您必须输入 IP 地址,数据将发送到该特定地址。目前,我可以发送,但在远程 IP 地址机器上,没有收到任何内容,反之亦然。请你能帮我理解为什么它不起作用。
public class UDPchat extends Thread
{
private final static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int port=1234; // port to send/receive datagrams on
String remoteIPaddress= null; // IP to send datagrams
// constructor, parameter is command line parameters
public UDPchat(String IPAdrr) throws Exception
{
System.out.println("chat program: IP address " + InetAddress.getLocalHost().toString() + " port " + port );
start(); // start thread to receive and display datagrams
// loop waiting for keyboard input, send datagram to remote IP
while(true)
try
{
String s = in.readLine(); // read a String
System.out.println("Sending to " + IPAdrr + " socket " + port + " data: " + s);
byte[] data = s.getBytes(); // convert to byte array
DatagramSocket theSocket = new DatagramSocket(); // create datagram socket and the datagram
DatagramPacket theOutput = new DatagramPacket(data, data.length, InetAddress.getByName(IPAdrr), port);
theSocket.send(theOutput); // and send the datagram
System.out.println("send everything");
start();
}
catch (Exception e) {System.out.println("Eroor sending datagram " + e);
// thread run method, receives datagram and display contents as a string
public void run()
{
try
{
// open DatagramSocket to receive
DatagramSocket ds = new DatagramSocket(port);
// loop forever reading datagrams from the DatagramSocket
while (true)
{
byte[] buffer = new byte[65507];
// array to put datagrams in
DatagramPacket dp = new DatagramPacket(buffer, buffer.length); // DatagramPacket to hold the datagram
ds.receive(dp);
// wait for next datagram
String s = new String(dp.getData(),0,dp.getLength()); // get contenets as a String
System.out.println("UDP datagram length " + s.length()+ " from IP " + dp.getAddress() + " received: " + s );
}
}
catch (SocketException se) {System.err.println("chat error " + se); }
catch (IOException se) {System.err.println("chat error " + se);}
System.exit(1); // exit on error
}
public static void main(String args[]) throws Exception
{
Scanner in = new Scanner(System.in);
String remoteIPaddress = in.nextLine();
UDPchat c=new UDPchat(remoteIPaddress);
}
}
首先,对于消息服务,您应该使用 TCP
可靠性。
UDP 用于实时通信,其中最新数据更为重要。
考虑到您的问题,如果您的计算机位于不同的网络中,可能是因为路由器完成了网络地址转换。
我相信您正在向正确的 IP 地址发送数据包,但端口不正确。您可能将数据包发送到的端口是机器的本地端口。
您需要将数据包发送到路由器分配的端口(或外部端口)。
当数据包从计算机A通过路由器到达计算机B时,路由器将计算机的本地端口映射到某个随机的外部端口。
所以,如果计算机B需要向计算机A发送数据包,那么计算机B需要在路由器分配给计算机A的外部IP:port上进行回复。然后路由器会转发给电脑A本地IP:port
我建议先了解UDP时这个映射是如何创建的
数据包通过网络内部或外部的路由器传输。
在使用 TCP/UDP 内容之前,请仔细阅读一些网络概念,例如网络地址转换、UDP 打洞。
这些来源可能有帮助:
RFC 4787 NAT Behavioral Requirements UDP
你也可以在这里参考我对same/similar问题的一些回答:
How to Send A UDP packet via public IP through NAT?
How to send an UDP message for an array of clients (java)
UDP Image transfer works depending on network
我必须创建一个程序来发送和接收消息 to/from 一个远程 IP 地址。所以基本上它应该模拟消息服务。在程序中,您必须输入 IP 地址,数据将发送到该特定地址。目前,我可以发送,但在远程 IP 地址机器上,没有收到任何内容,反之亦然。请你能帮我理解为什么它不起作用。
public class UDPchat extends Thread
{
private final static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int port=1234; // port to send/receive datagrams on
String remoteIPaddress= null; // IP to send datagrams
// constructor, parameter is command line parameters
public UDPchat(String IPAdrr) throws Exception
{
System.out.println("chat program: IP address " + InetAddress.getLocalHost().toString() + " port " + port );
start(); // start thread to receive and display datagrams
// loop waiting for keyboard input, send datagram to remote IP
while(true)
try
{
String s = in.readLine(); // read a String
System.out.println("Sending to " + IPAdrr + " socket " + port + " data: " + s);
byte[] data = s.getBytes(); // convert to byte array
DatagramSocket theSocket = new DatagramSocket(); // create datagram socket and the datagram
DatagramPacket theOutput = new DatagramPacket(data, data.length, InetAddress.getByName(IPAdrr), port);
theSocket.send(theOutput); // and send the datagram
System.out.println("send everything");
start();
}
catch (Exception e) {System.out.println("Eroor sending datagram " + e);
// thread run method, receives datagram and display contents as a string
public void run()
{
try
{
// open DatagramSocket to receive
DatagramSocket ds = new DatagramSocket(port);
// loop forever reading datagrams from the DatagramSocket
while (true)
{
byte[] buffer = new byte[65507];
// array to put datagrams in
DatagramPacket dp = new DatagramPacket(buffer, buffer.length); // DatagramPacket to hold the datagram
ds.receive(dp);
// wait for next datagram
String s = new String(dp.getData(),0,dp.getLength()); // get contenets as a String
System.out.println("UDP datagram length " + s.length()+ " from IP " + dp.getAddress() + " received: " + s );
}
}
catch (SocketException se) {System.err.println("chat error " + se); }
catch (IOException se) {System.err.println("chat error " + se);}
System.exit(1); // exit on error
}
public static void main(String args[]) throws Exception
{
Scanner in = new Scanner(System.in);
String remoteIPaddress = in.nextLine();
UDPchat c=new UDPchat(remoteIPaddress);
}
}
首先,对于消息服务,您应该使用 TCP 可靠性。
UDP 用于实时通信,其中最新数据更为重要。
考虑到您的问题,如果您的计算机位于不同的网络中,可能是因为路由器完成了网络地址转换。
我相信您正在向正确的 IP 地址发送数据包,但端口不正确。您可能将数据包发送到的端口是机器的本地端口。 您需要将数据包发送到路由器分配的端口(或外部端口)。
当数据包从计算机A通过路由器到达计算机B时,路由器将计算机的本地端口映射到某个随机的外部端口。
所以,如果计算机B需要向计算机A发送数据包,那么计算机B需要在路由器分配给计算机A的外部IP:port上进行回复。然后路由器会转发给电脑A本地IP:port
我建议先了解UDP时这个映射是如何创建的 数据包通过网络内部或外部的路由器传输。
在使用 TCP/UDP 内容之前,请仔细阅读一些网络概念,例如网络地址转换、UDP 打洞。
这些来源可能有帮助:
RFC 4787 NAT Behavioral Requirements UDP
你也可以在这里参考我对same/similar问题的一些回答:
How to Send A UDP packet via public IP through NAT?
How to send an UDP message for an array of clients (java)
UDP Image transfer works depending on network