2014-02-19 40 views
-3

我有一個Java應用程序輸入圖像,給出了許多選項來編輯它們(裁剪,調整大小),然後將它們導出到本地存儲。如何爲Java應用程序提供網絡功能?

我目前正嘗試使用java.net將服務器附加到此應用程序,但運行到幾個問題,因爲我從來沒有這樣做過。

  1. 我有激活服務器的圖形用戶界面的按鈕,這樣應用程序可以接收命令 - 問題是服務器使用while循環,不會停止,直到它與客戶斷開連接,這意味着程序直到那時才能運行。我假設它需要創建一個新線程,但是如何在不創建新實例的情況下向應用發送命令?
  2. 我想通過服務器將圖像從客戶端發送到應用程序。目前使用JFileChooser來選擇圖像的客戶端,但是如何將它發送到流中並在另一端重新創建它?

我的代碼只是修改了此clientserver的版本。它只是刪除回顯功能並根據客戶端發送的字符串運行一個方法。 (例如客戶端發送「打開」,以服務器 - 服務器運行開放(){}方法

編輯: 代碼:

這是服務器代碼ImageGUI是與所有的命令的GUI。並保持openImage方法 私人INT PORTNUMBER = 8888;

public Server() { 

    try (
    // Create Server socket 
    ServerSocket theServer = new ServerSocket(portNumber); 
      // Create socket for client 
      Socket clientSocket = theServer.accept(); 
      // Use to write to client 
      PrintWriter out = new PrintWriter(
        clientSocket.getOutputStream(), true); 
      // Used to read from client 
      BufferedReader in = new BufferedReader(new InputStreamReader(
        clientSocket.getInputStream()));) { 
     // Waits for Client commands 
     String clientCommand; 
     while ((clientCommand = in.readLine()) != null) { 
      if (clientCommand.contains("open")) { 
       // Runs open method in ImageGUI 
       new ImageGUI().openImage(); // I don't want this because it 
              // will create another GUI 
              // I want to run the openImage() 
              // in the GUI already open 
      } 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 
+0

向我們展示一些代碼。 – 2014-02-19 15:41:08

+0

'但是如何在不創建新實例的情況下向應用程序發送命令?咦? – SLaks

+0

我在代碼中添加了一條評論來解釋我的意思。 – user2916314

回答

0
  1. 可以使用共享BlockingQueue發送和消耗命令

    BlockingQueue是線程安全的。使用take()可讓您的服務器等待下一個命令,並使用主線程中的add()將命令添加到隊列中。

    然後,您可以使用類,枚舉甚至字符串來表示命令,並將它們從主線程發送到您的服務器線程。

  2. 要發送圖像,請使用客戶端的OutputStreamechoSocket.getOutputStream())寫入數據。服務器端,使用InputStreamclientSocket.getInputStream())來接收數據。

    例如:

    // Client side 
    int returnVal = chooser.showOpenDialog(parent); 
    if(returnVal == JFileChooser.APPROVE_OPTION) { 
        File imageFile = chooser.getSelectedFile(); 
    
        try(FileInputStream imageInputStream = new FileInputStream(imageFile); 
         OutputStream serverOutputStream = echoSocket.getOutputStream()) { 
         int[] buffer = new int[1024]; 
         int readCount = imageInputStream.read(buffer); 
         while(readCount > 0) { 
          serverOutputStream.write(buffer, 0, readCount); 
          readCount = imageInputStream.read(buffer); 
         } 
        } 
    } 
    

    和:

    // Server side 
    File folder = new File("/tmp/"); 
    File imageFile = new File(folder, "image.jpg"); 
    
    try(InputStream clientInputStream = clientSocket.getInputStream(); 
         FileOutputStream imageOutputStream = new FileOutputStream(imageFile)) { 
         int[] buffer = new int[1024]; 
         int readCount = clientInputStream.read(buffer); 
         while(readCount > 0) { 
          imageOutputStream.write(buffer, 0, readCount); 
          readCount = clientInputStream.read(buffer); 
         } 
        } 
    } 
    
+0

非常感謝,我會試試看。 – user2916314

0

你也許希望在自己的線程運行服務器的accept()循環。

您的服務器GUI的「啓動服務器」按鈕將啓動此線程。確保你還有一個「停止服務器」按鈕,它告訴服務器線程退出。同時告訴服務器線程在用戶退出應用程序時退出。

您將需要決定發送圖像的協議

它可能很簡單,只需將圖像文件中的字節向下推入套接字,然後關閉套接字即可 - 或者它可能更復雜一些,比如將數據塊中的字節包裝在表明數據包有多大的標頭中,它的用途等等。

或者它可能是其他人發明的預先存在的協議 - 在這種情況下,您可以使用庫實現。許多人會爲此使用HTTP。

+0

謝謝,我還有幾個跟進問題。這些圖像正在使用OpenCV的Mat格式進行編輯,但使用BufferedImages進行顯示時,您推薦使用什麼方法傳輸圖像?我怎樣才能讓一個按鈕停止服務器? – user2916314

+0

單擊按鈕時,調用serverThread.stop()。服務器實現的任何體面的例子都會有stop()方法。 – slim

+0

至於從BufferedImage獲取要寫入網絡的東西 - 使用與寫入文件相同的方法,但不使用FileOutputStream,而是寫入您選擇的任何協議。 – slim

相關問題