我要直截了当,这是与作业相关的,但作业是关于使用 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*/}
}
}