2011-04-26 70 views
2

從服務器請求特定的文件,我發現一些代碼,客戶端和服務器之間傳輸文件。但是文件位置和端口號是硬編碼的。我想知道是否有一種方法可以讓客戶端指定服務器需要哪些文件 - 這樣,當服務器收到請求時,它可以將該特定文件發送給客戶端。謝謝。通過套接字在Java中


編輯[1]:代碼片段和背景介紹:

我加入我到目前爲止的代碼的基礎上,反饋和評論。希望這可以在評論部分回答一些問題。

import java.net.*; 
import java.io.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* Original coder adapted from: 
* http://www.rgagnon.com/javadetails/java-0542.html 
* 
* Best intentions: 
* This program runs both as server and client. 
* 
* The client asks for a specific file from _ 
* the server x number of times in a loop. 
* 
* Server simply serves the file requested. 
*/ 

public class FileServer extends Thread { 

    public static void server() throws IOException { 
     ServerSocket servsock = new ServerSocket(13267); 
     while (true) { 
      System.out.println("Waiting..."); 

      Socket sock = servsock.accept(); 
      System.out.println("Accepted connection : " + sock); 

      //Retrieve filename to serve 
      InputStream is = sock.getInputStream(); 
      BufferedReader bfr = new BufferedReader(new InputStreamReader(is)); 
      String fileName = bfr.readLine(); 
      bfr.close(); 

      System.out.println("Server side got the file name:" + fileName); 

      //Sendfile 
      File myFile = new File(fileName); 
      byte[] mybytearray = new byte[(int) myFile.length()]; 
      FileInputStream fis = new FileInputStream(myFile); 
      BufferedInputStream bis = new BufferedInputStream(fis); 
      bis.read(mybytearray, 0, mybytearray.length); 
      OutputStream os = sock.getOutputStream(); 
      System.out.println("Sending..."); 
      os.write(mybytearray, 0, mybytearray.length); 
      os.flush(); 
      sock.close(); 
     } 
    } 

    public static void client(int index) throws IOException { 
     int filesize = 6022386; // filesize temporary hardcoded 

     long start = System.currentTimeMillis(); 
     int bytesRead; 
     int current = 0; 
     //Localhost for testing 
     Socket sock = new Socket("127.0.0.1", 13267); 

     System.out.println("Connecting..."); 

     //Ask for specific file: source1 
     String fileName = "source1"; 
     OutputStream os = sock.getOutputStream(); 
     PrintWriter pw = new PrintWriter(os); 
     pw.println(fileName); 


     //Receive file 
     byte[] mybytearray = new byte[filesize]; 
     InputStream is = sock.getInputStream(); 
     FileOutputStream fos = new FileOutputStream("source1-copy" + index); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     bytesRead = is.read(mybytearray, 0, mybytearray.length); 
     current = bytesRead; 

     // thanks to A. Cádiz for the bug fix 
     do { 
      bytesRead = 
        is.read(mybytearray, 
          current, (mybytearray.length - current)); 
      if (bytesRead >= 0) { 
       current += bytesRead; 
      } 
     } while (bytesRead > -1); 

     bos.write(mybytearray, 0, current); 
     bos.flush(); 

     long end = System.currentTimeMillis(); 
     System.out.println(end - start); 
     os.flush(); 

     bos.close(); 
     sock.close(); 
    } 

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

     FileServer fs = new FileServer(); 
     fs.start(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(
        FileServer.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     for (int i = 0; i < 5; i++) { 
      client(i); 
     } 

    } 

    @Override 
    public void run() { 
     try { 
      server(); 
     } catch (IOException ex) { 
      Logger.getLogger(
        FileServer.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

當我運行此代碼時,它在「連接...」行卡住了。下面是輸出:

等待...
接受的連接:插座[ADDR =/127.0.0.1,端口= 44939,將localPort = 13267]
連接...

+2

什麼協議,你說什麼? HTTP? FTP? – 2011-04-26 17:01:26

+0

只需使用標準化文件複製協議之一,如scp,http或(shudder)ftp。 – fvu 2011-04-26 17:02:15

+0

當您發出HTTP請求時,您肯定會請求特定的文件(我想這就是您所說的)。服務器對此請求及其參數做什麼,是您的配置中的選擇。 – 2011-04-26 17:04:44

回答

2

@ moejoe我認爲你在想這個。

如果你在的地方,已發送文件有它,然後做的第一件事是抽象的這個功能,所以你可以作爲一種方法運行它,並提供一個路徑/文件名。

然後你就可以使用socket(這是雙向)從客戶端發送信息到服務器,要求你想要的文件。除此之外,這是一個如何從UI中獲取所需文件的問題。您可能需要讓服務器提供「列出可用文件」的方法,即ls功能。

這都是相當微不足道的實施。

+0

@glowcoder我認爲你是對的。我根據您的建議修改了我的代碼,但現在我遇到了一個新問題。請參閱我的編輯。謝謝。 – moejoe 2011-04-26 18:44:55

+0

@moejoe就我個人而言,我不會將字節從客戶端發送到服務器。我只是用一個字符串發送消息 - 解析和處理起來更容易。將你的OutputStream包裝在PrintWriter中,並使用一個新的BufferedReader(new InputStreamReader(sock.getInputStream())'。然後在客戶端中你可以執行'pw.println(filename);'並在你的服務器上執行'String filename = br.readLine();' – corsiKa 2011-04-26 18:59:57

+0

@glowcoder我做了更改,但問題仍然存在,代碼被卡在「Connecting ...」中,正如我在編輯中提到的那樣。創建線程? – moejoe 2011-04-26 19:09:24