2015-12-29 30 views
0
import java.io.*; 
import java.net.*; 
import java.io.FileInputStream; 
import java.io.FilterInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.lang.reflect.Field; 
import java.nio.ByteBuffer; 
import java.nio.channels.AsynchronousCloseException; 
import java.nio.channels.FileChannel; 

class StreamCopier implements Runnable { 
private InputStream in; 
private BufferedOutputStream out; 

public StreamCopier(InputStream in, BufferedOutputStream out) 
{ 
    this.in = in; 
    this.out = out; 
} 

public void run() 
{ 
    try 
    { 
     int n; 
     byte[] buffer = new byte[4096]; 
     while ((n = in.read(buffer)) != -1) 
     { 
      out.write(buffer, 0, n); 
      out.flush(); 
     } 
    } 
    catch (IOException e) 
    { 
     System.out.println(e); 
    } 
} 
} 

class InputCopier implements Runnable 
{ 

private BufferedInputStream in; 
private OutputStream out; 

public InputCopier(BufferedInputStream in, OutputStream out) 
{ 
    this.in = in; 
    this.out = out; 
} 

public void run() 
{ 
    try 
    { 
     int n; 
     byte buffer[] = new byte[4096]; 
     while ((n = in.read(buffer)) != -1) 
     { 
      out.write(buffer, 0, n); 
      out.flush(); 
     } 
     out.close(); 
    } 
    catch (AsynchronousCloseException e) 
    { 
    } 
    catch (IOException e) 
    { 
     System.out.println(e); 
    } 
} 
} 

public class Test 
{ 
    private static Socket socket; 

public static void main(String[] args)throws IOException, InterruptedException, NoSuchFieldException, IllegalAccessException 
{ 
    try 
    { 
     ServerSocket serverSocket=new ServerSocket(5000); 
     socket=serverSocket.accept(); 

     BufferedInputStream in=new BufferedInputStream(socket.getInputStream()); 
     BufferedOutputStream out=new BufferedOutputStream(socket.getOutputStream()); 
    //  BufferedOutputStream err=new BufferedOutputStream(socket.getErrorStream()); 
     Process process = Runtime.getRuntime().exec("java Hello"); 

     Thread outThread = new Thread(new StreamCopier(process.getInputStream(), out)); 
     outThread.start(); 

    // Thread errThread = new Thread(new StreamCopier(process.getErrorStream(), err)); 
    // errThread.start(); 

     Thread inThread = new Thread(new InputCopier(in, process.getOutputStream())); 
     inThread.start(); 

     process.waitFor(); 
     System.in.close(); 
     outThread.join(); 
    // errThread.join(); 
     inThread.join(); 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     try 
     { 
      socket.close(); 
     } 
     catch(Exception e) 
     { 
      System.out.println(e); 
     } 
    } 
} 
} 

测试类包含服务器套接字程序打印输出到JTextArea中超过在Java客户端服务器网络

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

class User 
{ 
private static Socket socket; 

public static void main(String args[]) 
{ 
    try 
    { 
     socket = new Socket("localhost",5000); 
     Thread t1 = new A(socket); 
     t1.start(); 
     Thread t2 = new B(socket); 
     t2.start(); 

     t1.join(); 
     t2.join(); 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     try 
     { 
      socket.close(); 
     } 
     catch(Exception e) 
     { 
      System.out.println(e); 
     } 
    } 
} 
} 
class B extends Thread 
{ 
Socket socket; 
B(Socket socket) 
{ 
    this.socket=socket; 
} 
public void run() 
{ 
    try 
    { 
     BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 
     InputStream in=System.in; 
     int n; 
     byte buffer[] = new byte[4096]; 
     while ((n = in.read(buffer)) != -1) 
     { 
      out.write(buffer, 0, n); 
      out.flush(); 
     } 
    } 
    catch(Exception e) 
    {} 
} 
} 
class A extends Thread 
{ 
Socket socket; 
A(Socket socket) 
{ 
    this.socket=socket; 
} 
public void run() 
{ 
    try 
    { 
     BufferedInputStream in = new BufferedInputStream(socket.getInputStream()); 
     OutputStream out = System.out; 

     int n; 
     byte[] buffer = new byte[4096]; 
     while ((n = in.read(buffer)) != -1) 
     { 
      out.write(buffer, 0, n); 
      out.flush(); 
     } 
    } 
    catch(Exception e) 
    {} 
} 
} 

用户类含客户端套接字程序。

程序 Output of program

的输出我想打印过程的输出到JTextArea中,并通过输入通过JTextField的处理。

UI代码。

import java.awt.EventQueue; 
import javax.swing.JFrame; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.JButton; 


public class Client { 

private JFrame frame; 
private JTextField textField; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       Client window = new Client(); 
       window.frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

/** 
* Create the application. 
*/ 
public Client() { 
    initialize(); 
} 

/** 
* Initialize the contents of the frame. 
*/ 
private void initialize() { 
    frame = new JFrame(); 
    frame.setBounds(100, 100, 450, 300); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().setLayout(null); 

    JTextArea txtrTextAreaFor = new JTextArea(); 
    txtrTextAreaFor.setText("Text Area For Output of process"); 
    txtrTextAreaFor.setBounds(36, 11, 289, 143); 
    frame.getContentPane().add(txtrTextAreaFor); 

    textField = new JTextField(); 
    textField.setBounds(36, 165, 191, 43); 
    frame.getContentPane().add(textField); 
    textField.setColumns(10); 

    JButton btnSubmit = new JButton("Submit"); 
    btnSubmit.setBounds(236, 185, 89, 23); 
    frame.getContentPane().add(btnSubmit); 
} 
} 
+0

使用的SwingWorker读取来自流的内容,使用发布/处理功能,从事件指派线程 – MadProgrammer

+1

的范围内更新的文本框看一看[并发在Swing(HTTP:// docs.oracle.com/javase/tutorial/uiswing/concurrency/)和[Worker Threads and SwingWorker](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html)了解更多详情 – MadProgrammer

回答

2

所以,我写这完全是我的头未经测试的顶部,所以它可能需要一些调整

Swing是单线程架构,它也是不是线程安全的。这意味着你不应该做任何可能阻塞事件分派线程的事情,比如读写Socket,你绝不应该从事件分派线程之外更新UI。

有关更多详细信息,请参阅Concurrency in Swing

现在,很少有解决方案,最简单的可能是使用SwingWorker,它允许您在后台线程中执行一些关闭EDT的处理(长时间运行/阻塞),但它提供了一个许多简单的方法可以安全地将数据同步回UI。

查看Worker Threads and SwingWorker了解更多详情。

本例中使用SwingWorker同时为WriteWorkerReadWorker,从技术上说,你不需要使用SwingWorker的写操作,因为你没有真正与UI交互,但我这样做,因为它稍微简化错误管理。

public class SocketThread implements Runnable { 

    private String host; 
    private int port; 

    private JTextArea ta; 

    private WriteWorker writeWorker; 
    private ReadWorker readWorker; 

    private CountDownLatch shutDownLatch; 

    public SocketThread(String host, int port, JTextArea ta) { 
     this.host = host; 
     this.port = port; 
     this.ta = ta; 
    } 

    public void write(String text) { 
     if (writeWorker != null) { 
      if (writeWorker.getState() == SwingWorker.StateValue.STARTED) { 
       writeWorker.write(text); 
      } else { 
       throw new IllegalStateException("Write worker is not running"); 
      } 
     } else { 
      throw new NullPointerException("Write worker is nul"); 
     } 
    } 

    public void close() { 
     if (writeWorker != null) { 
      writeWorker.cancel(true); 
     } 
     if (readWorker != null) { 
      readWorker.cancel(true); 
     } 

     // Force the CountDownLatch to release 
     if (shutDownLatch != null) { 
      shutDownLatch.countDown(); 
      shutDownLatch.countDown(); 
     } 
    } 

    @Override 
    public void run() { 
     try (Socket socket = new Socket(host, port)) { 
      writeWorker = new WriteWorker(socket.getOutputStream()); 
      readWorker = new ReadWorker(socket.getInputStream(), ta); 

      writeWorker.addPropertyChangeListener(new PropertyChangeHandler()); 
      readWorker.addPropertyChangeListener(new PropertyChangeHandler()); 

      writeWorker.execute(); 
      readWorker.execute(); 

      shutDownLatch = new CountDownLatch(2); 
      shutDownLatch.await(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    protected class PropertyChangeHandler implements PropertyChangeListener { 

     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      SwingWorker worker = (SwingWorker) evt.getSource(); 
      if (worker.getState() == SwingWorker.StateValue.DONE) { 
       shutDownLatch.countDown(); 

       // Not interested in the return value, only interested in the 
       // exception if one was thrown... 
       try { 
        worker.get(); 
       } catch (InterruptedException | ExecutionException ex) { 
        // Resync the error with the UI, probably using SwingUtilities.invokeLater 
        // and call some error handling method 
        ex.printStackTrace(); 
       } 
      } 
     } 

    } 

} 

public class WriteWorker extends SwingWorker { 

    private OutputStream os; 

    private List<String> queue = new ArrayList<String>(25); 
    private ReentrantLock queueLock = new ReentrantLock(); 
    private Condition queueCondition = queueLock.newCondition(); 

    public WriteWorker(OutputStream os) { 
     this.os = os; 
    } 

    public void write(String text) { 
     queueLock.lock(); 
     try { 
      queue.add(text); 
      queueCondition.signal(); 
     } finally { 
      queueLock.unlock(); 
     } 
    } 

    @Override 
    protected Object doInBackground() throws Exception { 
     while (!isCancelled()) { 
      String text = null; 
      while (text == null && !isCancelled()) { 
       queueLock.lock(); 
       try { 
        if (queue.isEmpty()) { 
         queueCondition.await(); 
        } 

        if (!queue.isEmpty()) { 
         text = queue.remove(0); 
        } 
       } finally { 
        queueLock.unlock(); 
       } 
       if (text != null) { 
        os.write(text.getBytes()); 
       } 
      } 
     } 
     return null; 
    } 

} 

public class ReadWorker extends SwingWorker<Void, String> { 

    private InputStream is; 
    private JTextArea ta; 

    public ReadWorker(InputStream is, JTextArea ta) { 
     this.is = is; 
     this.ta = ta; 
    } 

    @Override 
    protected void process(List<String> chunks) { 
     for (String text : chunks) { 
      ta.append(text); 
     } 
    } 

    @Override 
    protected Void doInBackground() throws Exception { 
     byte[] buffer = new byte[4096]; 
     int bytesRead = -1; 
     while (!isCancelled() && (bytesRead = is.read(buffer)) != -1) { 
      String text = new String(buffer, 0, bytesRead); 
      publish(text); 
     } 
     return null; 
    } 

} 
相关问题