简体   繁体   English

通过UDP套接字发送数据时出现问题

[英]Problem sending data over UDP sockets

This is kind of a followup to the question I had yesterday. 这是我昨天提出的问题的后续措施。 I had a homework assignment to send and receive data with a client/server TCP socket connection. 我进行了一项家庭作业,以使用客户端/服务器TCP套接字连接发送和接收数据。 I would like to make a version of it using UDP. 我想使用UDP制作一个版本。 The idea is that I can redirect standard I/O and send the streams using UDP. 我的想法是,我可以重定向标准I / O并使用UDP发送流。 For example, if I type in: 例如,如果我输入:

 server: java UDPServer 5555 < file1.txt
 client: java UDPClient localhost 5555 > file2.txt

It should send the data in file1.txt from the server to client's file2.txt. 它应该将file1.txt中的数据从服务器发送到客户端的file2.txt。 When I run the client/server pair in separate terminals, file2.txt is created but the data is never actually sent. 当我在单独的终端中运行客户机/服务器对时,将创建file2.txt,但实际上不会发送数据。 Instead it seems like I am stuck in an infinite loop, where I cannot enter anything into the terminal unless I kill the application. 相反,似乎我陷入了无限循环,除非杀死应用程序,否则无法在终端中输入任何内容。

The server code is: 服务器代码为:

public static final int BUF_SIZE = 256;

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

    port = Integer.parseInt(args[0]);

    DatagramSocket serverSocket = new DatagramSocket(port);

    BufferedInputStream input = new BufferedInputStream(System.in);
    BufferedOutputStream output = new BufferedOutputStream(System.out);

    byte[] receiveData = new byte[BUF_SIZE];
    byte[] sendData = new byte[BUF_SIZE];
    byte[] buf = new byte[BUF_SIZE];
    String sentence;

    if(System.in.available() > 0) {
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        InetAddress address = receivePacket.getAddress();
        int bytesRead = 0;
        while((bytesRead = input.read(buf, 0, BUF_SIZE)) != -1) {
            sentence = new String(buf, 0, bytesRead);
            sendData = sentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
            serverSocket.send(sendPacket);
        }
    } else {
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        sentence = new String(receivePacket.getData());
        output.write(sentence.getBytes());
    }

    serverSocket.close();
    input.close();
    output.close();
}

And the client code is: 客户端代码为:

public static final int BUF_SIZE = 256;

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

    String hostName = args[0];
    port = Integer.parseInt(args[1]);

    DatagramSocket clientSocket = new DatagramSocket();
    InetAddress address = InetAddress.getByName(hostName);

    BufferedInputStream input = new BufferedInputStream(System.in);
    BufferedOutputStream output = new BufferedOutputStream(System.out);

    byte[] sendData = new byte[BUF_SIZE];
    byte[] receiveData = new byte[BUF_SIZE];
    byte[] buf = new byte[BUF_SIZE];
    String sentence;

    if(System.in.available() > 0) {
        int bytesRead = 0;
        while((bytesRead = input.read(buf, 0, BUF_SIZE)) != -1) {
            sentence = new String(buf, 0, bytesRead);
            sendData = sentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
            clientSocket.send(sendPacket);
        }
    } else {
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        clientSocket.receive(receivePacket);
        sentence = new String(receivePacket.getData());
        output.write(sentence.getBytes());
    }

    clientSocket.close();
    input.close();
    output.close();
}

I am still new to socket programming so I am basing this off of example code in my textbook. 我还是套接字编程的新手,所以我将其基于我的教科书中的示例代码。 Is there some glaring mistake that I am making that is preventing the data from being transferred? 我是否犯了一些明显的错误,即阻止了数据传输? Thanks very much for your patience and help! 非常感谢您的耐心配合和帮助!

The first problem you have is that client.main doesn't run because your shell command is wrong. 您遇到的第一个问题是,由于您的shell命令错误, client.main无法运行。 For some reason, with Java you can't redirect output how it's traditionally done. 由于某种原因,使用Java不能将输出重定向到传统方式。 You can simply put a few print statements at the beginning of client.main to see nothing executes. 您可以简单地在client.main的开头放置一些打印语句,以查看没有任何执行。 Try this: 尝试这个:

java UDPClient localhost 5555 | tee file2.txt

See redirect Java output . 请参阅重定向Java输出

The other problem you have is that both the client and server are waiting to receive a datagram. 您遇到的另一个问题是客户端和服务器都在等待接收数据报。 You have in the server code: 您在服务器代码中有:

if(System.in.available() > 0) {
    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);

And you have in the client code: 并且您在客户端代码中:

else {
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        sentence = new String(receivePacket.getData());
        output.write(sentence.getBytes());
        }

Note that the else statement will always execute because System.in.available will always return 0. Remember your not redirecting input to the client, so there's nothing in System.in . 请注意,else语句将始终执行,因为System.in.available将始终返回0。请记住,您没有将输入重定向到客户端,因此System.in中没有任何内容。 To fix this you need to first send a client datagram so that the server can respond with the contents of file2.txt . 要解决此问题,您需要首先发送客户端数据报,以便服务器可以使用file2.txt的内容进行响应

You're missing all the things you need to do to make this work. 您错过了完成这项工作所需要做的所有事情。 Where's the code to do transmit pacing, retransmissions, acknowledgements, reordering, and so on? 传输步调,重传,确认,重新排序等的代码在哪里? If you want to use UDP, you have to do yourself all the things TCP does for you. 如果要使用UDP,则必须自己完成TCP为您做的所有事情。

See, for example RFC 1350 for an example of a file transfer protocol layered on top of UDP. 有关在UDP之上分层的文件传输协议的示例,请参见RFC 1350

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM