【发布时间】:2023-09-26 12:18:01
【问题描述】:
这个问题被问了很多,但到目前为止,我从以前的答案中应用的解决方案都没有帮助我。
主要目标
我正在尝试学习 UDP conexions,这是我的尝试。我想让客户端通过 UDP 在服务器上请求图片,服务器将发送它。然后客户端将创建一个包含该信息的文件。
说明
我的主要想法是使用“GET”命令(不是 HTTP,只是 GET)向服务器请求图像,然后是图像的名称(包括扩展名)。然后客户端等待响应,即请求的图像。
问题
客户端等待并回答没有来
研究
从另一个类似的问题来看,我使用相同的端口进行接收和连接是一个问题,所以我添加了两个端口,接收端口和发送端口,客户端没有结果。
从其他类似的问题来看,这是一个防火墙问题。因此,在 Win10 机器上,我在防火墙中为我用于此应用程序的端口创建了一个新的 UDP 规则,但客户端没有收到任何内容...
我已检查图像是否已加载到byte[] 并已发送。但是在客户端上,什么都没有收到并停留在那里等待连接通过
来自服务器的代码
public class UDPserver {
static DatagramSocket serverUDP;
static DatagramPacket packet;
static InetAddress address;
static byte[] buffer = new byte[65507];//65507
final static int receivingPORT = 6668;
final static int sendingPORT = 6669;
public static void main(String[] args) throws SocketException, IOException, InterruptedException{
boolean serverActive = true;
String order = "";
String file = "";
//Instantiate server
serverUDP = new DatagramSocket(receivingPORT);
while(serverActive){
//Kind of packet we want to receive
packet = new DatagramPacket(buffer, buffer.length);
System.out.println("Server awaiting connection...");
//Receive it
serverUDP.receive(packet);
System.out.println("Received packet from: " + packet.getAddress() + "/" + packet.getPort());
//What does the packet contain?
String msg = new String(packet.getData());
address = packet.getAddress();
System.out.println("Order from: " + address + "/" + receivingPORT + " says: " + msg);
try{
order = msg.split(" ")[0].trim();
file = msg.split(" ")[1].trim();
} catch (Exception e){
}
switch(order){
case("GET"):{
System.out.println("Sending back an image...");
buffer = loadImageFromServer(file);
packet = new DatagramPacket(buffer, buffer.length, address, sendingPORT);
Thread.sleep(5000);
serverUDP.send(packet);
System.out.println("Client served");
break;
}
case("DISCONNECT"):{
buffer = "Server is disconnecting...".getBytes();
packet = new DatagramPacket(buffer, buffer.length, address, sendingPORT);
serverUDP.send(packet);
serverActive = false;
serverUDP.close();
break;
}
}
}
}
static byte[] loadImageFromServer(String path) {
try {
System.out.println("Loading path: " + path);
//Instantiate a buffer from the image for it
BufferedImage img = ImageIO.read(UDPserver.class.getResource(path));
//Create a byte[] stream object to handle the data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//Write the image data into those above with jpg format
ImageIO.write(img, "png", baos);
//Flush the information
baos.flush();
byte[] buffer = baos.toByteArray(); //Write it out on a byte string and return it
return buffer;
} catch (IOException ex) {
Logger.getLogger(UDPserver.class.getName()).log(Level.SEVERE, null, ex.fillInStackTrace());
System.exit(-1);
}
return null;
}
}
CODE 客户端
public class Client {
static DatagramSocket clientUDP;
static InetAddress address;
static DatagramPacket packetSend;
static DatagramPacket packetReceive;
static int SIZE = 65507;
final static int receivingPORT = 6669;
final static int sendingPORT = 6668;
static byte[] buffer = new byte[SIZE];
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) throws SocketException, UnknownHostException, IOException{
boolean clientLoop = true;
//Get address
address = InetAddress.getByName("localhost");
//Instantiate Client -> UDP
clientUDP = new DatagramSocket();
while(clientLoop){
System.out.print("Enter any key and press enter");
scan.next(); //Just to stop the loop
//Load the buffer
buffer = "GET imagenServidor.png".getBytes();
//buffer = "DISCONNECT".getBytes();
System.out.println("Buffer is ready");
//Arm the packet
packetSend = new DatagramPacket(buffer, buffer.length, address, sendingPORT);
System.out.println("Packet is armed!");
//Send the packet to the server
clientUDP.send(packetSend);
System.out.println("Order sent to server");
System.out.println("Waiting an answer");
packetReceive = new DatagramPacket(buffer, buffer.length, address, receivingPORT);
clientUDP.receive(packetReceive);
System.out.println("Server answered!");
ByteArrayInputStream bais = new ByteArrayInputStream(packetReceive.getData());
BufferedImage image = ImageIO.read(bais);
System.out.println(image);
}
clientUDP.close();
}
}
注意事项
- 这是一个 UDP 练习
【问题讨论】:
-
1.没有UDP连接之类的东西。 2、发送和接收使用同一个端口是没有问题的,不要这样浪费端口。 3. 您需要
ew ByteArrayInputStream(packetReceive.getData(), 0, packetReceive.getLength());4. 最重要的是,您可能未能发送 65507 字节的数据报。首先,您不能发送大于套接字发送缓冲区的数据报,并且在任何情况下,这实际上对于 UDP 来说太大了,对于大多数图像来说也太小了。基本上你不能这样做。使用 TCP。 -
我知道 TCP 可以完美地解决我的问题,但这是我必须理解的功课。我将尝试应用您的观点。谢谢
-
因为您必须使用 UDP 进行练习,所以您需要创建一个应用层协议来处理将流转换为比数据流小得多的单个消息。如果您使用大约 576 字节的数据大小,UDP 效果最好。实时协议,例如VoIP,在 UDP 上使用小得多(20 字节左右)的数据大小,因为 UDP 是无连接的,数据包会丢失。您需要考虑到这一点,并且您的协议必须重新请求传输中丢失的数据。
-
好评@RonMaupin。这将是完善分配的一个很好的补充,尽管现在我只是学习基础知识。我有一个解决方案,我将在之后发布一个我处理 Netbeans 文件路径问题...
标签: java sockets networking udp