1)问题:两个while循环是否同时运行?我想知道的是 main() 方法中的 while 循环正在运行,而 sendDATA 中的 while 循环正在执行?
2)如果不是我怎么能同时发送和接收。我必须实现 TFTP,所以我必须读取并发送每个数据包 512 个字节,所以:我读取 512 个字节并发送它们,然后等待 ACK 数据包从客户端到达 ACK Packet = |opcode|block#| 所以传入[0] = 3 和传入[1] = int 块#
如果传入的块编号与我发送的匹配,那么我可以发送下一个数据包,否则我必须发送前一个数据包。我不知道如何用一个循环来实现这一点。
我的代码:
package source;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.util.Scanner;
public class Server
{
static String[] errorcodes = {"Not defined", "File not found", "Access violation", "Disk full or allocation exceeded", "Illegal TFTP Operation",
"Unknown transfer ID", "File already exists", "No such user"};
static String FILE = "";
static String MODE = "";
static byte[] outgoing = new byte[512];
static byte[] incoming = new byte[512];
static DatagramSocket socket;
static String clientip;
static int clientport;
public static void main(String[] args) throws Exception
{
socket = new DatagramSocket(13373); // 69 Reserved for TFTP
// Listen for incoming packets
while(true) {
DatagramPacket packet = new DatagramPacket(incoming, incoming.length);
socket.receive(packet);
clientip = packet.getAddress().toString().replace("/", "");
clientport = packet.getPort();
System.out.println(clientport);
if(incoming[0] == 1 || incoming[0] == 2) {
handleRequest(incoming);
}
}
}
// sends DATA opcode = 3 : | opcode | block # | data |
private static void sendDATA() {
outgoing = new byte[512]; // Empty array
try {
ByteBuffer sDATA = ByteBuffer.allocate(516);
// 512 - 2 byte opcode, 2 byte block #, 512 data
DatagramPacket data = new DatagramPacket(outgoing, outgoing.length, InetAddress.getByName(clientip), clientport);
InputStream fis = new FileInputStream(new File(FILE));
int a;
int block = 1;
while((a = fis.read(outgoing,0,512)) != -1)
{
data.setLength(a);
sDATA.put((byte)3);
sDATA.put((byte)block);
sDATA.put(outgoing);
socket.send(data);
if(incoming[0] == 3 && incoming[1] == block)
{
}
}
} catch (Exception e) {
}
}
// Request packet: | opcode | filename | 0 | mode | 0 |
// Upravlja le z WRQ / RRQ opcode
private static void handleRequest(byte[] packet)
{
int opcode = packet[0];
String filename = "";
int offset = 0;
String mode = "";
// Get filename
for(int i = 1; i < packet.length; i++) {
if(packet[i] != 0) {
filename += (char)packet[i];
} else {
offset = i;
break;
}
}
// Get mode
for(int j = offset; j < packet.length; j++) {
if(packet[j] != 0) {
mode += (char)packet[j];
}
}
FILE = filename;
MODE = mode;
if(opcode == 1) {
// Do RRQ
File test = new File(filename);
if(test.exists()) {
sendACK();
} else {
sendERROR(1);
}
} else {
// Do WRQ
File test2 = new File(filename);
if(test2.exists()) {
sendERROR(6);
} else {
sendACK();
}
}
}
// send ACK opcode = 4 : | opcode | block # |
// block 0 -> prvi ACK, odgovor na RRQ/WRQ
// block 1 -> stevilo poslanega bloka, stetje blokov se zacne
// pri 1.
private static void sendACK() {
outgoing = new byte[512];
outgoing[0] = (byte)4;
outgoing[1] = (byte)0;
try {
DatagramPacket ackpacket = new DatagramPacket(outgoing, outgoing.length, InetAddress.getByName(clientip), clientport);
socket.send(ackpacket);
} catch(Exception e) {
}
}
// send ERROR packet opcode = 5 : | opcode | errorcode | msg | 0 |
// General errorcodes: 2
private static void sendERROR(int errorcode) {
ByteBuffer errpack = ByteBuffer.allocate(512);
errpack.put((byte)5); // opcode
errpack.put((byte)errorcode); // errorcode
try {
errpack.put(errorcodes[errorcode].getBytes("US-ASCII")); // msg
errpack.put((byte)0);
outgoing = errpack.array(); // Pack ERROR Packet
DatagramPacket errpacket = new DatagramPacket(outgoing, outgoing.length, InetAddress.getByName(clientip), clientport);
socket.send(errpacket);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}