2017-02-18 1 views
0

Я работаю над некоторым кодом для взаимодействия с сервером и отправки файла в 1000 байт. Я хочу использовать setSoTimeout для повторной отправки пакета через 5 секунд, если к тому времени я не получил ACK с сервера. Я искал ответ на этот вопрос, но безрезультатно. Вот некоторые ссылки я проверил и покушения:Как использовать setSoTimeout для повторной отправки пакета через определенный промежуток времени?

What is the functionality of setSoTimeout and how it works?

how to use socket.setSoTimeout()?

setSotimeout on a datagram socket

Я нахожусь под впечатлением, что, когда таймер будет вы постоянно ждете ACK. Это так? Я никогда не получаю ACK с сервера, хотя я был в какой-то момент раньше.

import java.net.*; 
import java.io.*; 
import java.util.*; 

public class FTPClient { 

    Socket tcpSocket; 
    DatagramSocket udpSocket; 
    DataInputStream dataIn; 
    DataOutputStream dataOut; 
    BufferedReader br; 
    String fileName; 
    int time; 
    int portNum; 

/** 
* Constructor to initialize the program 
* 
* @param serverName server name 
* @param server_port server port 
* @param file_name  name of file to transfer 
* @param timeout  Time out value (in milli-seconds). 
*/ 
public FTPClient(String server_name, int server_port, String file_name, int timeout) { 

    System.out.println("Server Name: " + server_name + " Server Port: " + server_port 
     + " File Name: " + file_name + " Timeout: " + timeout); 

    fileName = file_name; 
    time = timeout; 
    portNum = server_port; 
    try { 

     Socket tcpSocket = new Socket(server_name, server_port);  
     dataIn = new DataInputStream(tcpSocket.getInputStream()); 
     dataOut = new DataOutputStream(tcpSocket.getOutputStream()); 
     br = new BufferedReader(new InputStreamReader(System.in)); 


    } 
    catch (Exception ex) { 
     System.out.println("Exception in FTPClient initialization: " + ex); 
    } 
} 

/** 
*Send file content as Segments 
* 
*/ 

public void send() { 

    try { 

     File f = new File(fileName); 

     if (!f.exists()) { 
      System.out.println("File does not exist..."); 
      return; 
     } 

     System.out.println("Sending filename (" + fileName + ") to server."); 
     dataOut.writeUTF(fileName); 

     byte msgFromServer = dataIn.readByte(); 

     if (msgFromServer == 0) { 
      System.out.println("Server ready to receive file"); 
     } 

     // Create a UDP socket to send the file to the server 
     DatagramSocket udpSocket = new DatagramSocket(); 


     InetAddress IPAddress = InetAddress.getByName("localhost"); 

     FileInputStream fileIn = new FileInputStream(f); 

     int seqNum = 0; 
     int i = 0; 

     Boolean received = false;; 

     byte[] chunks = new byte[1000]; 
     int rc = fileIn.read(chunks); 

     while(rc != -1) 
     { 
      System.out.println("Iteration #: " + i); 
      System.out.println(rc); 
      // rc should contain the number of bytes read in this operation. 

      //if (rc < 1000) { 
       //System.out.println("Bytes read less than 1000"); 
       //System.out.println("Sequence Number: " + seqNum); 
       //System.out.println("Packet too small to send"); 

      //} 


       System.out.println("Bytes read greater than 1000"); 
       System.out.println("Sequence Number: " + seqNum); 


       while (received == false) { 
        System.out.println("You are looping and sending again"); 
        transferPacket(seqNum, IPAddress, chunks); 
        received = getResponse(); 

       } 


       rc = fileIn.read(chunks); 
       if (seqNum == 1) { 
        seqNum = 0; 
       }     
       else { 
        seqNum = 1; 
       } 

       i++; 

     } 

    } 
    catch (Exception e) { 
     System.out.println("Error: " + e); 
    } 

} 

public Boolean getResponse() { 
    try { 
     DatagramSocket udpSocket = new DatagramSocket(); 

     System.out.println("You are in getResponse()"); 
     byte[] receiveData = new byte[1000]; 
     udpSocket.setSoTimeout(time); // set timer 

     while (true) { 
      try { 
       System.out.println("You are receiving a packet"); 
       DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 
       udpSocket.receive(receivePacket); 
       Segment unwrap = new Segment(receivePacket); 

       int num = unwrap.getSeqNum(); 
       System.out.println("Received ACK with Sequence Number: " + num); 
       return true; 

      } 
      catch (SocketTimeoutException t) { 
       System.out.println("Timeout: return false to send()"); 
       return false; 
      } 
     } 
    } 
    catch (Exception e) { 
     System.out.println("You don't wanna be here"); 
     return false; 
    } 
} 



public void transferPacket(int seqNum, InetAddress IPAddress, byte[] chunks) { 

    try { 
     DatagramSocket udpSocket = new DatagramSocket(); 

     byte[] sendData = new byte[1000]; 

     Segment s = new Segment(seqNum, chunks); 
     sendData = s.getBytes();   

     DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, portNum); 
     udpSocket.send(sendPacket); 
     System.out.println("Sent Packet with sequence number " + seqNum); 
    } 
    catch (Exception e) { 
     System.out.println("Exception in transferPacket: " + e); 
    } 
} 

/** 
* A simple test driver 
*  
*/ 
public static void main(String[] args) { 

    String server = "localhost"; 
    String file_name = ""; 
    int server_port = 8888; 
    int timeout = 5000; // milli-seconds (this value should not be changed) 


    // check for command line arguments 
    if (args.length == 3) { 
     // either provide 3 parameters 
     server = args[0]; 
     server_port = Integer.parseInt(args[1]); 
     file_name = args[2]; 
    } 
    else { 
     System.out.println("Wrong number of arguments, try again."); 
     System.out.println("Usage: java FTPClient server port file"); 
     System.exit(0); 
    } 

    FTPClient ftp = new FTPClient(server, server_port, file_name, timeout); 


    System.out.printf("Sending file \'%s\' to server...\n", file_name); 
    try { 
     ftp.send(); 
    } 
    catch (Exception e) { 
     System.out.println("Exception: " + e); 
    } 
    System.out.println("File transfer completed."); 

} 

} 
+0

Похоже, вы изобретаете TCP через UDP. Почему бы просто не использовать TCP? –

+0

Я должен попробовать сделать это вот так. Вы имеете в виду, что я инициирую подключение через tcp, а затем отправляю файл через udp? – AndieM

ответ

0

Вы должны продолжать использовать тот же UDP сокет для жизни приложения, а не новый в пакете, и использовать его для отправки и приема.

В настоящее время вы также испытываете утечку UDP-разъемов, как пожарный.

Смежные вопросы