尝试做一个rdt3.0的程序,代码如下
sender:import java.io.*;
import java.net.*;
import java.util.*;
public class sender { /**
 * @param args
 * @throws Exception 
 */

InetAddress IPAddress;
int emuPort, recPort;
BufferedReader File;
PrintWriter seqlog, acklog;
DatagramSocket sendSocket;
DatagramSocket receiveSocket;
Timer timer;
TimerTask task;
DatagramPacket curPacket;
int i; 
boolean done;
boolean received;

public sender(String host, String emuP, String recP, String name) throws Exception{ IPAddress = InetAddress.getByName(host);
emuPort = Integer.parseInt(emuP);
recPort = Integer.parseInt(recP);
File = new BufferedReader(new FileReader(name));
seqlog = new PrintWriter("seqnum.log");
acklog = new PrintWriter("ack.log");
sendSocket = new DatagramSocket();
receiveSocket = new DatagramSocket(recPort);
i=0;

done = true;
received = true;
timer = new Timer();
task = new TimerTask(){
public void run(){
try {
send();
received = false;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
};
}

public void send() throws Exception{


byte[] sendData = new byte[512];
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length,IPAddress, emuPort);
if(received){
char[] text = new char[500];
int read = File.read(text);
System.out.println("seqNum to be sent"+ i);
System.out.println("Content sent: ");
System.out.print(text);
if (read == -1){
sendData = packet.createEOT(i).getUDPdata();
sendSocket.send(sendPacket);
seqlog.println(i);

}else{
packet sendP = packet.createPacket(i, new String(text));
sendData = sendP.getUDPdata();
sendSocket.send(sendPacket);
seqlog.println(sendP.getSeqNum()+'\n');
System.out.println("Packet Sent"+'\n');
}
curPacket = sendPacket;
}
else if(!received){
sendSocket.send(curPacket);
seqlog.println(i);
}


}

public void receive() throws Exception {
byte[] receiveData = new byte[512];

DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
receiveSocket.receive(receivePacket);
packet ack = packet.parseUDPdata(receivePacket.getData());
if (ack.getType() == 0 && ack.getSeqNum() == (i%2)){
acklog.println(ack.getSeqNum()+'\n');
System.out.println("Packet Received:" + i);
i++;
received = true;
task.cancel();

}
if (ack.getType() == 2 && ack.getSeqNum() == (i%2)){

task.cancel();
done = false;
}

}

public void transmit() throws Exception{

while(done){
send();
timer.schedule(task, 500);
receive();
}
File.close();
seqlog.close();
acklog.close();
sendSocket.close();
receiveSocket.close();
}

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

// TODO Auto-generated method stub
sender s = new sender(args[0], args[1], args[2], args[3]);
s.transmit();


}}receiver:
import java.io.*;
import java.net.*;public class receiver {

InetAddress IPAddress;
int emuPort; 
int recPort;
PrintWriter arrlog;
PrintWriter write;
DatagramSocket receiveSocket;
DatagramSocket sendSocket;
int i;
/**
 * @param args
 */

public receiver(String host, String e, String s, String file_name) throws Exception{
IPAddress = InetAddress.getByName(host);
emuPort = Integer.parseInt(e);
recPort = Integer.parseInt(s);
write = new PrintWriter(file_name);
arrlog = new PrintWriter("arrival.log");
receiveSocket = new DatagramSocket(recPort);
sendSocket = new DatagramSocket();
i = 0;
}

public void transmit() throws Exception{
boolean done = true;
byte[] receiveData = new byte[512];
byte[] sendData = new byte[512];
DatagramPacket sendPacket;

while(done){
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
receiveSocket.receive(receivePacket);
packet recP = packet.parseUDPdata(receivePacket.getData());
arrlog.println(recP.getSeqNum()+"\n");

if(recP.getSeqNum() == i){
if(recP.getType() == 2){
done = false;
packet stop = packet.createEOT(recP.getSeqNum());
sendData = stop.getUDPdata();
sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, emuPort);
sendSocket.send(sendPacket);
} else{
System.out.println("Sequence Number:" + i);
packet ack = packet.createACK(i);
sendData = ack.getUDPdata();
sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, emuPort);
sendSocket.send(sendPacket);
i++;
i%=2;
write.print(new String(recP.getData()));
System.out.println(new String(recP.getData())+"/n");
}
}
}

arrlog.close();
write.close();
receiveSocket.close();
sendSocket.close();
}
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
receiver r = new receiver(args[0], args[1], args[2], args[3]);
r.transmit();

}}packet:// common packet class used by both SENDER and RECEIVERimport java.nio.ByteBuffer;public class packet {

// constants
private final int maxDataLength = 500;
private final int SeqNumModulo = 2;

// data members
private int type;
private int seqnum;
private String data;

//////////////////////// CONSTRUCTORS //////////////////////////////////////////

// hidden constructor to prevent creation of invalid packets
private packet(int Type, int SeqNum, String strData) throws Exception {
// if data seqment larger than allowed, then throw exception
if (strData.length() > maxDataLength)
throw new Exception("data too large (max 500 chars)");

type = Type;
seqnum = SeqNum % SeqNumModulo;
data = strData;
}

// special packet constructors to be used in place of hidden constructor
public static packet createACK(int SeqNum) throws Exception {
return new packet(0, SeqNum, new String());
}

public static packet createPacket(int SeqNum, String data) throws Exception {
return new packet(1, SeqNum, data);
}

public static packet createEOT(int SeqNum) throws Exception {
return new packet(2, SeqNum, new String());
}

///////////////////////// PACKET DATA //////////////////////////////////////////

public int getType() {
return type;
}

public int getSeqNum() {
return seqnum;
}

public int getLength() {
return data.length();
}

public byte[] getData() {
return data.getBytes();
}

//////////////////////////// UDP HELPERS ///////////////////////////////////////

public byte[] getUDPdata() {
ByteBuffer buffer = ByteBuffer.allocate(512);
buffer.putInt(type);
        buffer.putInt(seqnum);
        buffer.putInt(data.length());
        buffer.put(data.getBytes(),0,data.length());
return buffer.array();
}

public static packet parseUDPdata(byte[] UDPdata) throws Exception {
ByteBuffer buffer = ByteBuffer.wrap(UDPdata);
int type = buffer.getInt();
int seqnum = buffer.getInt();
int length = buffer.getInt();
byte data[] = new byte[length];
buffer.get(data, 0, length);
return new packet(type, seqnum, new String(data));
}
}
还有一个网络模拟器nEmulator-linux386会定时抛弃packet。
发送文件总会出现Task already scheduled or cancelled exception,不知道该如何解决,求解决!timer

解决方案 »

  1.   


     public void run(){
                    try {
                        send();
                        received = false;
                    } catch (Exception e) {
                        // TODO Auto-generated catch block//为何不在这里做一些异常的处理呢,比如重启之类的
                        e.printStackTrace();
                    }
                     
                }