//*******************************************server.javaimport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Arrays;public class server {
private Thread thread = null; public server() {
}
public void start(int port) {
stop();
thread = new ServerSocketThread(port);
thread.start();
}
public void stop() {
if (thread == null)
return;
((ServerSocketThread) thread)._stop = true;
thread.interrupt();
}
@SuppressWarnings("deprecation")
public void pause() {
if (thread == null)
return;
thread.suspend();
}
@SuppressWarnings("deprecation")
public void resume() {
if (thread == null)
return;
thread.resume();
}
}class ServerSocketThread extends Thread {
volatile boolean _stop = false;
private int port = 0;
private ServerSocket server = null; public ServerSocketThread(int port) {
this.port = port;
} public void run() {
try {
server = new ServerSocket(this.port);
server.setSoTimeout(300);
while (!_stop && !server.isClosed()) {
try {
Socket client = server.accept();
SocketThread thread = new SocketThread(client);
thread.start();
}
catch (SocketTimeoutException e) {
}
}
server.close();
}
catch (IOException e) {
e.printStackTrace();
// _stop = true; // 在异常处理代码中修改共享变量的状态
}
// catch (InterruptedException e) {}
}
}class SocketThread extends Thread {
volatile boolean stop = false; private Socket client = null; public SocketThread(Socket client) {
this.client = client;
} public void run() {
if (client == null)
return;
try {
// 由系统标准输入输出设备构造BufferedReader,PrintWriter对象
BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
PrintWriter sysout = new PrintWriter(System.out); // 由Socket对象得到输出流构造BufferedReader,PrintWriter对象
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream()); while (!stop && !client.isClosed()) {
byte[] buf = new byte[200];
Arrays.fill(buf, (byte) 0);
int len = client.getInputStream().read(buf);
if (len == -1)
break;
sysout.println(new String(buf, 0, len));
sysout.flush(); // out.println(new String(buf, 0, len));
// out.flush();
} client.close();
}
catch (IOException e) {
e.printStackTrace();
// stop = true; // 在异常处理代码中修改共享变量的状态
}
// catch (InterruptedException e) {}
}
}
//*******************这个为ui界面的代码
//*******************main.java
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;public class main extends JFrame {
private JPanel jContentPane = null;
private JButton btnBind = null;
private JButton btnSend = null;
private JTextField txtPort = null;
private JTextArea txtList = null;
private JTextField txtMsg = null;
private JScrollPane pnlScroll = null; private server srv = null; public main() {
super();
initialize();
}
private void initialize() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setContentPane(getJContentPane());
this.setName("frmMain");
this.setSize(400, 324);
this.setTitle("server");
this.setResizable(false);
this.setLocationRelativeTo(getOwner());
srv = new server();
}
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(null); // new BorderLayout()
jContentPane.setSize(new java.awt.Dimension(317, 205));
jContentPane.add(getBtnBind(), null);
jContentPane.add(getBtnSend(), null);
jContentPane.add(getTxtPort(), null);
jContentPane.add(getTxtMsg(), null);
jContentPane.add(getPnlScroll(), null);
}
return jContentPane;
} private JScrollPane getPnlScroll() {
if (pnlScroll == null) {
pnlScroll = new JScrollPane(getTxtList());
pnlScroll.setBounds(new java.awt.Rectangle(4, 33, 387, 232)); // 设置水平和垂直滚动条需要时出现
pnlScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pnlScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
}
return pnlScroll;
} private JTextArea getTxtList() {
if (txtList == null) {
txtList = new JTextArea();
}
return txtList;
}
private JTextField getTxtPort() {
if (txtPort == null) {
txtPort = new JTextField();
txtPort.setBounds(new java.awt.Rectangle(4, 4, 315, 22));
txtPort.setText("12580");
txtPort.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER)
btnBind.doClick();
}
});
}
return txtPort;
} private JTextField getTxtMsg() {
if (txtMsg == null) {
txtMsg = new JTextField();
txtMsg.setBounds(new java.awt.Rectangle(4, 271, 315, 23));
txtMsg.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER)
btnSend.doClick();
}
});
}
return txtMsg;
} private JButton getBtnBind() {
if (btnBind == null) {
btnBind = new JButton();
btnBind.setBounds(new java.awt.Rectangle(322, 4, 68, 22));
btnBind.setText("Bind");
btnBind.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
int port = Integer.parseInt(txtPort.getText());
// txtList.append("hello world!" + port + "\r\n");
System.out.println("onBtnBind()-------------");
srv.start(port);
}
});
}
return btnBind;
} private JButton getBtnSend() {
if (btnSend == null) {
btnSend = new JButton();
btnSend.setBounds(new java.awt.Rectangle(322, 271, 68, 22));
btnSend.setText("Send");
btnSend.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
System.out.println("onBtnSend()-------------");
srv.stop();
}
});
}
return btnSend;
} public static void main(String[] args) {
main application = new main();
application.show();
}
}
当客户端发来消息时,在控件
private JTextArea txtList = null;
里显示;当用户点击按钮
private JButton btnSend = null;
时,将文本框
private JTextField txtMsg = null;
里的信息向所有连接的客户端发送
线程ServerSocketThread中怎么样从
Socket client = server.accept();
这里的阻塞中跳出?线程SocketThread中怎么样从
int len = client.getInputStream().read(buf);
这里的阻塞中跳出?问题2.*********************
线程中的socket获得及发出的消息怎么样跟ui交互
即:
1).客户端发来消息时,怎么从线程中一直推到ui?
2).ui中文本框里的信息,怎么样用socket发出去?
2、调用inputstream的close方法,则阻塞read方法上抛出IOException问题2,看不懂,图形没搞过
你的clientThread中//这两个outputstream,你没有往后者里写东西,那client如何能收到;
PrintWriter sysout = new PrintWriter(System.out);
PrintWriter out = new PrintWriter(client.getOutputStream());
你对每一个socket请求都用一个独立的线程操作,是打算处理多个client?
那你socket中是不是得有区分client的标识,如IP什么的,不能每次都用新的线程,
Socket client = server.accept();
这里的阻塞中跳出?这个应该不用跳出来的,当有客户机连接的时候,他会处理事情,然后继续监听。不然也起不了服务器的作用呀
线程SocketThread中怎么样从
int len = client.getInputStream().read(buf);
这里的阻塞中跳出?这里应该是有个while循环的 当读到的数据为-1的时候,自然就跳出来的。
问题2
socket 获得的消息就是一个字符串,那么你想对字符串怎样操作都是你自己的设定啥。你可以写入XML文件,也可以字节调用UI中的setText();之类的方法设置。ui中一个有什么getText()方法获得字符串,然后传给socket啥。
根据你这句话,我觉得你是在做多连接的,
但处理socket请求的线程中,处理结束后就关闭了当前的socket,这样不可能保持多用户啊;
SocketThread 中的 client.close();
要是只给当前请求的用户回信,如5楼,应该在client.getOutputStream中写返回信息
1、每个client连上来后,要记录IP,你可以用list来存放
2、因为你存在主动向client发送数据的情况,所以,client必须有个 tcp 或者 udp的server来接收你的消息。
只是我有个凝问
因为Socket是线程里面的东西-------------------------------------
问题2其实是说线程安全的
发送接收的东西要跟ui打交道
所以怎么解决线程里操作ui的安全问题
//************************server.java
import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Arrays;public class server {
private Thread thread = null; public server() {
}
public void start(int port) {
stop();
thread = new ServerSocketThread(port);
thread.start();
}
public void stop() {
if (thread == null)
return;
((ServerSocketThread) thread)._stop = true;
thread.interrupt();
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public void pause() {
if (thread == null)
return;
thread.suspend();
}
@SuppressWarnings("deprecation")
public void resume() {
if (thread == null)
return;
thread.resume();
}
}class ServerSocketThread extends Thread {
volatile boolean _stop = false;
private int port = 0;
private ServerSocket server = null;
private java.util.List<Thread> clients; public ServerSocketThread(int port) {
this.port = port;
clients = new ArrayList<Thread>();
} public void run() {
try {
server = new ServerSocket(this.port);
server.setSoTimeout(300);
while (!_stop && !server.isClosed()) {
try {
Socket client = server.accept();
SocketThread thread = new SocketThread(client);
clients.add(thread);
thread.start();
}
catch (SocketTimeoutException e) {
}
} for (int i = 0; i < clients.size(); i++) {
SocketThread thread = (SocketThread) clients.get(i);
thread._stop = true;
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
clients.clear(); server.close();
}
catch (IOException e) {
e.printStackTrace();
// _stop = true; // 在异常处理代码中修改共享变量的状态
}
// catch (InterruptedException e) {}
}
}class SocketThread extends Thread {
volatile boolean _stop = false;
private Socket client = null; public SocketThread(Socket client) {
this.client = client;
} public void run() {
if (client == null)
return;
try {
// 由系统标准输入输出设备构造BufferedReader,PrintWriter对象
BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
PrintWriter sysout = new PrintWriter(System.out); // 由Socket对象得到输出流构造BufferedReader,PrintWriter对象
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream()); client.setSoTimeout(300);
while (!_stop && !client.isClosed()) {
try {
byte[] buf = new byte[200];
Arrays.fill(buf, (byte) 0);
int len = client.getInputStream().read(buf);
if (len == -1)
break;
sysout.println(new String(buf, 0, len));
sysout.flush(); // out.println(new String(buf, 0, len));
// out.flush();
}
catch (SocketTimeoutException e) {
}
} client.close();
}
catch (IOException e) {
e.printStackTrace();
// stop = true; // 在异常处理代码中修改共享变量的状态
}
// catch (InterruptedException e) {}
}
}
改了一点点,使用Socket,ServerSocket的join()方法,解决了等待线程结束的问题
java.io.PipedInputStream
java.io.PipedOutputStream
那多线程需要操作ui时,一般做法是将操作转到主线程里面去。比如mfc,vcl的SendMessage,qt发送事件
java的ui(awt,swing)也不是线程安全的
线程ServerSocketThread中怎么样从
Socket client = server.accept();
这里的阻塞中跳出?NIO有非阻塞式的实现,不过现实起来稍微复杂一点问题2.*********************
线程中的socket获得及发出的消息怎么样跟ui交互
即:
1).客户端发来消息时,怎么从线程中一直推到ui?
2).ui中文本框里的信息,怎么样用socket发出去?1)可以不断的把Runnable对象Post出去,直到找到UI线程为止
2)不明白,不是把数据发到client端的socket来发就可以了么?
SwingWorker