2013-04-07 108 views
0

我打算挺直了,这是作业相关的,但作业是关于使用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*/} 
    } 

} 
+0

如何添加生成的输出粘贴?另外,客户端和服务器绑定了哪些端口号? – 2013-04-07 19:17:53

+0

此代码的输出是,socket.recieve函数一遍又一遍地超时。客户端和服务器分别绑定到9876和9875。此外,在构造函数中输出inetaddress和端口号的打印函数会输出“null -1” – Sidney 2013-04-07 23:36:28

+0

此代码的输出缺少在您尝试发送未收到数据时所抛出的所有异常,因为你在捕捉并忽略它们。不要这样做。 – EJP 2013-04-08 04:06:37

回答

1

您的代码是错误的。

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

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

  3. 您绝不能忽略异常。不要欺骗他们不会发生,或者如果他们这样做,他们可以被忽略。它们会发生,而且不容忽视。在这种情况下,如果你没有忙于忽略它,你在发送之前会发现一个例外情况(2)。

相关问题