关于rdt中timer问题
尝试做一个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 RECEIVER
import 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 --------------------编程问答--------------------
public void run(){
try {
send();
received = false;
} catch (Exception e) {
// TODO Auto-generated catch block//为何不在这里做一些异常的处理呢,比如重启之类的
e.printStackTrace();
}
}
补充:Java , Java EE