环回地址不接收数据报包

时间:2013-04-07 16:52:04

标签: java

我会直接上去,这是与家庭作业相关的,但是家庭作业是关于使用UDP实现TCP风格的数据可靠性保证,而不是UDP套接字tom-foolery,这是我的问题所在。

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

第二类是我遇到问题的地方。在接收类中,我试图接收数据,但它永远不会到达那里。使用packetsniff,我发现在该套接字上甚至没有接收调用在运行代码时,它会在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*/}
    }

}

1 个答案:

答案 0 :(得分:2)

你的代码错了。

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

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

  3. 您绝不能忽略异常。不要嘲笑他们不会发生,或者他们可以被忽视。他们会发生,他们不容忽视。在这种情况下,如果您没有如此忙于忽略它,那么在发送时会有一个例外(2),如果您没有那么忙,那么就会有例外。