0

我要直截了当,这是与作业相关的,但作业是关于使用 UDP 实现 TCP 样式的数据可靠性保证,而不是 UDP 套接字 tom-foolery,这是我的问题所在。

所以我已经为一个Java程序辛勤工作了几个小时,我开始认为我不会找到答案。我在eclipse中使用两个类,一个发送一个UDP数据报包,我已经用socketsniff验证了它被绑定并发送到环回地址并具有正确格式的有效负载。

第二个是课堂是我有问题的地方。在接收类中,我试图接收数据,但它永远不会到达那里。使用 packetniff,我发现该套接字上什至没有接收调用运行代码时,它会在 socket.receive() 调用之前到达 println 语句,但它只是不运行它。奇怪的是,它会超时!为什么收不到?

这是我的接收类代码。

package us.wsu.compnet.reliabletransfer;

import java.io.*;
import java.net.*;

/**
 * This class implements a receiver of the Stop-And-Wait reliable transfer protocol
 */
public class MyServerSocket implements Runnable {

    private PipedOutputStream internalOutputStream; // Stream to which we write data for the upper layer
    private PipedInputStream upperLayerStream; // Stream given to upper layer, connected to internalOutputStream

    private DatagramSocket sock;
    private DatagramPacket pack;
    private byte[] buf;
    private int seqNum;

    /**
     * Creates a receiver socket on a given port. 
     */
    public MyServerSocket(int port) throws SocketException {
        // Open the UDP socket.
        sock = new DatagramSocket(port);
        System.out.println("" + sock.getInetAddress()  + " " + sock.getPort() + "\n");
        buf = new byte[1000];
        pack = new DatagramPacket(buf,buf.length);
        seqNum = 0;

        // Create stream to the upper layer.
        internalOutputStream = new PipedOutputStream();
        try {upperLayerStream = new PipedInputStream(internalOutputStream);}
            catch (IOException e) {/* This should not happen. */}

        // Start thread that will receive the data packets and reply with acks.
        (new Thread(this)).start();
        }

    /**
     * Returns the InputStream associated with the socket. 
     */
    public InputStream getInputStream() {
        return upperLayerStream;
    }

    /**
     * Implementation of the receiver protocol.
     */
    public void run() {
        try{
        // Receive datagram.
        int x = 0;
        sock.setSoTimeout(10000);
        while (x < 10000)
        {
            try{                
                System.out.println("Waiting to recieve packet");
                sock.receive(pack);
                System.out.println("Packet Recieved");
            }
            catch(Exception e){
                System.out.println("Swingandamiss!");
            }
        x++;
        }
        // Extract sequence number and data payload.
        MyDataPacket p;
        pack.setData(buf,0,pack.getLength()-1);
        p = new MyDataPacket(buf,buf.length-1);

        // If packet is received for the first time, deliver to upper layer.
        if ( p.getSeqNum() == seqNum)
        {
            internalOutputStream.write(p.getData(), 0, p.getData().length);
            seqNum = (byte) (1-seqNum);
        }       

        // Send ack.
        MyAckPacket ack;
        ack = new MyAckPacket(seqNum);
        DatagramPacket pout;
        pout = new DatagramPacket(ack.toByteArray(),ack.toByteArray().length);
        DatagramSocket outSock;
        outSock = new DatagramSocket(pack.getPort(),pack.getAddress());
        outSock.send(pout);
        }
        catch (IOException e){/*Do Nothing*/}
    }

}
4

1 回答 1

2

你的代码是错误的。

  1. 您应该使用相同的 DatagramSocket 进行发送和接收。您尝试使用源地址构建新代码的代码完全不正确,甚至不适用于非本地源。它还会泄漏套接字。

  2. 您必须创建一个 DatagramPacket 以使用目标地址和端口进行发送。在响应的情况下,简单的方法是使用请求数据报并仅更改其数据,保持地址:端口不变。

  3. 您绝不能忽略异常。不要自欺欺人说它们不会发生,或者如果发生了它们可以被忽略。它们会发生,它们不能被忽视。在这种情况下,如果您没有忙于忽略它,那么您在发送时会遇到异常,该异常会告诉您有关 (2) 的信息。

于 2013-04-08T03:27:47.820 回答