私は初心者で、これについてのチュートリアルを調べましたが、これを正確に実装する方法がまだわかりません。
main() メソッドに 1 つと send() メソッドに 1 つの 2 つの while ループがあり、両方を同時に実行する必要があります。
public static void main(String[] args) throws Exception
{
socket = new DatagramSocket(13373); // 69 Reserved for TFTP
// Listen for incoming packets
while(true) {
// Do things
}
}
private static void sendDATA() {
while(true) {
// Do things
}
}
sendDATA の while ループは、ファイルから 512 バイトを読み取り、それらをクライアント クラスに送信することによって機能します。メインメソッドのループがクライアントからパケットを受信し、変数がtrueの場合に変数を更新している間、sendDATAは次の512バイトを読み取って送信しますが、2つのスレッドで作業できません.
これを 1 つの while ループで実行すると、プログラムが動作し、最後のパケット以外のすべてのパケットが転送されます。クライアントは最後のパケットを取得しません。
サーバ:
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() {
try {
ByteBuffer sDATA = ByteBuffer.allocate(514);
byte[] tmp = new byte[512];
DatagramPacket data = new DatagramPacket(sDATA.array(), sDATA.array().length, InetAddress.getByName(clientip), clientport);
InputStream fis = new FileInputStream(new File(FILE));
int a;
int block = 1;
while((a = fis.read(tmp,0,512)) != -1)
{
data.setLength(a);
sDATA.put((byte)3);
sDATA.put((byte)block);
System.out.println(sDATA.array().length);
sDATA.put(tmp);
System.out.println(tmp.length);
socket.send(data);
socket.setSoTimeout(60000);
while(true) {
DatagramPacket getack = new DatagramPacket(incoming, incoming.length);
try {
socket.receive(getack);
if(incoming[0] == 4 && incoming[1] == block) {
break;
} else if(incoming[0] == 4 && incoming[1] == block && tmp.length < 511) {
fis.close();
break;
}
} catch (SocketTimeoutException e) {
socket.send(data);
continue;
}
}
block++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
クライアント:
public static void main(String[] args) throws Exception
{
clientSocket = new DatagramSocket(8571);
// WRQ || RRQ
Scanner input = new Scanner(System.in);
int opcode = input.nextInt(); input.close();
// Pripravi paketek
outgoing = makeRequestPacket(opcode,"filename.txt","US-ASCII");
// Odposlje pakete
sendPacket(outgoing);
// Streznik vrne ACK - opcode 4 ali ERROR - opcode 5
// Pri ACK zacnemo posiljat DATA opcode 3 drugace prekinemo povezavo ob ERROR - opcode 5
while(true) {
DatagramPacket receiveResponse = new DatagramPacket(incoming, incoming.length);
clientSocket.receive(receiveResponse);
// opcode 5 - ERROR
if(incoming[0] == 5) {
getError(incoming);
}
else if(incoming[0] == 4 && incoming[1] == 0) { // opcode 4 - Prvi ACK
System.out.print("opcode: (" + incoming[0] +") ACK received operation confirmed.");
continue;
}
else if(incoming[0] == 3) {
System.out.println("Ah got a data packet.");
File initfile = new File("filename2.txt");
if(!initfile.exists()) {
initfile.createNewFile();
}
int block;
FileOutputStream fio = new FileOutputStream(initfile);
if(incoming.length > 511) {
block = incoming[1];
System.out.println("Will start to write.");
for(int i = 2; i < incoming.length; i++) {
fio.write(incoming[i]);
}
ByteBuffer recack = ByteBuffer.allocate(514);
recack.put((byte)4);
recack.put((byte)block);
System.out.println("If i came here and nothing happened something went horribly wrong.");
DatagramPacket replyACK = new DatagramPacket(recack.array(), recack.array().length, InetAddress.getByName("localhost"),13373);
clientSocket.send(replyACK);
} else if (incoming.length < 511) {
System.out.println("Last chunk.");
block = incoming[1];
for(int j = 2; j < incoming.length; j++) {
if(incoming[j] != 0) {
fio.write(incoming[j]);
} else {
break;
}
}
ByteBuffer recack = ByteBuffer.allocate(514);
recack.put((byte)4);
recack.put((byte)block);
DatagramPacket replyACK = new DatagramPacket(recack.array(), recack.array().length, InetAddress.getByName("localhost"),13373);
clientSocket.send(replyACK);
fio.close();
clientSocket.close();
break;
}
continue;
}
}
}