2014-02-19 39 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

相关问题