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);
}
}
}
}
测试类包含服务器套接字程序
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 :(得分:2)
所以,我在没有测试的情况下将这完全写在了我的头顶,所以可能需要一些调整
Swing是一个单线程框架,它也不是线程安全的。这意味着你不应该做任何阻止事件调度线程的事情,比如读/写Socket
,你永远不应该从事件调度线程之外更新UI。
有关详细信息,请查看Concurrency in Swing。
现在,这个解决方案很少,最简单的可能就是使用SwingWorker
,这允许你在后台线程中从EDT做一些处理(长时间运行/阻塞),但是它提供了许多简单的方法来安全地将数据同步回UI。
有关详细信息,请参阅Worker Threads and SwingWorker。
此示例对SwingWorker
和WriteWorker
使用ReadWorker
,从技术上讲,您不需要使用SwingWorker
进行写操作,因为您和#39;并没有真正与用户界面进行交互,但我已经这样做了,因为它简化了错误管理。
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;
}
}