我用swt designer做了一个Application window(main.java)作为客户端,与服务器端双向通信,客户端作为main.java的一个内部类。在窗口输入ip,端口号等信息后按下按钮启动客户端线程。但线程启动后非常卡,没几秒就没响应了,只有开始那几秒能收到服务器发送的消息并显示出来
客户端代码如下
class server implements Runnable{
ServerSocket server;
Socket client;
InputStream in;
OutputStream out;
int port;
public void setPort(int port) {
this.port = port;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
server=new ServerSocket(port);
client=server.accept();
text_4.append("客户机是:"+client.getInetAddress().getHostName()+"\n\n");
in=client.getInputStream();
out=client.getOutputStream();
}catch(IOException ioe){}
while(true){
try{
byte[]buf=new byte[256];
in.read(buf);
String str=new String(buf);
text_4.append("\n客户机说:"+str+"\n");
Thread.sleep(1000);
}catch (IOException e){} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void close(){
System.exit(0);
}
public void send(String s){
try{
byte[]buf=s.getBytes();
out.write(buf);
}catch(IOException ioe){}
}
客户端代码如下
class server implements Runnable{
ServerSocket server;
Socket client;
InputStream in;
OutputStream out;
int port;
public void setPort(int port) {
this.port = port;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
server=new ServerSocket(port);
client=server.accept();
text_4.append("客户机是:"+client.getInetAddress().getHostName()+"\n\n");
in=client.getInputStream();
out=client.getOutputStream();
}catch(IOException ioe){}
while(true){
try{
byte[]buf=new byte[256];
in.read(buf);
String str=new String(buf);
text_4.append("\n客户机说:"+str+"\n");
Thread.sleep(1000);
}catch (IOException e){} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void close(){
System.exit(0);
}
public void send(String s){
try{
byte[]buf=s.getBytes();
out.write(buf);
}catch(IOException ioe){}
}
1.循环中动态分配空间 byte[]buf=new byte[256];
2.in.read会阻塞,如果客户端每次发的正好是256还好,否则就会阻塞
try{
byte[]buf=new byte[256];
in.read(buf);
String str=new String(buf);
text_4.append("\n客户机说:"+str+"\n");
Thread.sleep(1000);你这个无限循环new了无限个String:String str=new String(buf);
我一开始也觉得是这里的问题,但我在别的程序那里看到同样的代码,运行起来却情况良好
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Client1 extends Frame implements ActionListener{
Label label=new Label("交谈内容");
Panel panel=new Panel();
TextField tf=new TextField(20);
TextArea ta=new TextArea();
Socket client;
InputStream in;
OutputStream out;
public Client1(){
super("客户机");
setSize(250,250);
panel.add(label);
panel.add(tf);
tf.addActionListener(this);
add("South",panel);
add("Center",ta);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
show();
try{
client=new Socket(InetAddress.getLocalHost(),1000);
ta.append("服务器是:"+client.getInetAddress().getHostAddress()+"\n\n");
in=client.getInputStream();
out=client.getOutputStream();
}catch(IOException ioe){}
while(true)
{
try{
byte[]buf=new byte[256];
in.read(buf);
String str=new String(buf);
ta.append("\n服务器说:"+str+"\n");
}
catch(IOException e){}
}
}
public void actionPerformed(ActionEvent e){
try{
String str=tf.getText();
byte[]buf=str.getBytes();
tf.setText(null);
out.write(buf);
ta.append("\n我说:"+str+"\n");
}catch(IOException ioe){}
}public static void main(String[]args){
new Client1();
}
}import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
public class Server extends Frame implements ActionListener
{
Label label=new Label("交谈内容");
Panel panel=new Panel();
TextField tf=new TextField(20);
TextArea ta=new TextArea();
ServerSocket server;
Socket client;
InputStream in;
OutputStream out;
public Server()
{
super("服务器");
setSize(250,250);
panel.add(label);
panel.add(tf);
tf.addActionListener(this);
add("South",panel);
add("Center",ta);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
show();
try{
server=new ServerSocket(1000);
client=server.accept();
ta.append("客户机是:"+client.getInetAddress().getHostName()+"\n\n");
in=client.getInputStream();
out=client.getOutputStream();
}catch(IOException ioe){}
while(true){
try{
byte[]buf=new byte[256];
in.read(buf);
String str=new String(buf);
ta.append("\n客户机说:"+str+"\n");
}catch (IOException e){}
}
}
public void actionPerformed(ActionEvent e){
try{
String str=tf.getText();
byte[]buf=str.getBytes();
tf.setText(null);
out.write(buf);
ta.append("\n我说:"+str+"\n");
}catch(IOException ioe){}
}
public static void main(String[]args)
{
new Server();
}
}
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;import javax.swing.AbstractListModel;
import javax.swing.text.DefaultStyledDocument;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
public class main { protected Shell shell;
private Text text_4;
private Text text_5;
private String localIP;
protected Socket client_socket;//与Server连接的Soket client c ;
private ServerSocket server;
private Text text;
/**
* Launch the application.
* @param args
*/
public static void main(String[] args) {
try {
main window = new main();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* Open the window.
*/
public void open() { Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} /**
* Create contents of the window.
*/
protected void createContents() {
shell = new Shell();
shell.setSize(613, 577);
shell.setText("SWT Application");
Group group = new Group(shell, SWT.NONE);
group.setBounds(0, 0, 202, 308);
Group group_1 = new Group(group, SWT.NONE);
group_1.setText("\u901A\u8BAF\u6A21\u5F0F");
group_1.setBounds(10, 10, 182, 110);
final Button btnRadioButton = new Button(group_1, SWT.RADIO);
btnRadioButton.setBounds(30, 22, 93, 16);
btnRadioButton.setText("TCP Client");
btnRadioButton.setSelection(true);
final Button btnRadioButton_1 = new Button(group_1, SWT.RADIO);
btnRadioButton_1.setBounds(30, 47, 93, 16);
btnRadioButton_1.setText("TCP Server");
Button btnRadioButton_2 = new Button(group_1, SWT.RADIO);
btnRadioButton_2.setBounds(30, 72, 93, 16);
btnRadioButton_2.setText("UDP");
Group group_2 = new Group(group, SWT.NONE);
group_2.setText("\u8BBE\u7F6E");
group_2.setBounds(10, 126, 182, 127);
Label label = new Label(group_2, SWT.NONE);
label.setBounds(10, 21, 54, 12);
label.setText("\u8FDC\u7A0B\u4E3B\u673A");
final Combo combo = new Combo(group_2, SWT.NONE);
combo.setBounds(85, 63, 87, 20);
combo.setText("1000");
final Combo combo_1 = new Combo(group_2, SWT.NONE);
combo_1.setTouchEnabled(true);
combo_1.setBounds(85, 89, 87, 20);
combo_1.setText("1000");
combo_1.setEnabled(false);
Label label_1 = new Label(group_2, SWT.NONE);
label_1.setBounds(10, 66, 54, 12);
label_1.setText("\u8FDC\u7A0B\u7AEF\u53E3");
Label label_2 = new Label(group_2, SWT.NONE);
label_2.setBounds(10, 92, 54, 12);
label_2.setText("\u672C\u5730\u7AEF\u53E3");
text = new Text(group_2, SWT.BORDER);
text.setBounds(10, 42, 162, 18);
Group group_3 = new Group(group, SWT.NONE);
group_3.setBounds(10, 260, 182, 37);
final Button button = new Button(group_3, SWT.NONE);
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {//启动,关闭服务器,客户端或udp
if(btnRadioButton.getSelection()==true){//启动客户端
if(button.getText()=="连接网络"){
try {
System.out.println(Integer.parseInt(combo.getText()));
button.setText("断开网络");
c =new client();
c.setIp(text.getText());
c.setPort(Integer.parseInt(combo.getText()));
c.run();
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
button.setText("连接网络");
MessageBox mb = new MessageBox(shell,SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
mb.setMessage("输入有误");
mb.open(); e1.printStackTrace();
} catch (Exception e1) {
// TODO Auto-generated catch block
button.setText("连接网络");
MessageBox mb = new MessageBox(shell,SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
mb.setMessage("输入有误或连接断开");
mb.open();
e1.printStackTrace();
}
}
else{
c.close();
button.setText("连接网络");
}
}
else if(btnRadioButton_1.getSelection()==true){//启动,关闭服务器
}
else{//启动,关闭UDP
}
}
});
button.setBounds(56, 10, 72, 22);
button.setText("\u8FDE\u63A5\u7F51\u7EDC");
Group group_5 = new Group(shell, SWT.NONE);
group_5.setBounds(0, 349, 202, 59);
Button button_3 = new Button(group_5, SWT.NONE);
button_3.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {//手动发送
//String message_readytosend =text_5.getText();
try {
//sendmessage(text_5.getText());
c.send(text_5.getText());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
button_3.setBounds(105, 20, 72, 22);
button_3.setText("\u624B\u52A8\u53D1\u9001");
text_4 = new Text(shell, SWT.MULTI|SWT.BORDER|SWT.WRAP|SWT.V_SCROLL);
text_4.setBounds(225, 26, 353, 244);
text_5 = new Text(shell, SWT.MULTI);
text_5.setBounds(228, 308, 350, 167);
getIP();
Group group_8 = new Group(shell, SWT.NONE);
group_8.setBounds(225, 0, 353, 270);
Label label_6 = new Label(group_8, SWT.NONE);
label_6.setBounds(152, 10, 72, 12);
label_6.setText("\u6570\u636E\u63A5\u6536\u533A");
Group group_9 = new Group(shell, SWT.NONE);
group_9.setBounds(225, 276, 353, 199);
Label label_7 = new Label(group_9, SWT.NONE);
label_7.setBounds(156, 12, 70, 12);
label_7.setText("\u6570\u636E\u53D1\u9001\u533A");
localIP="";
btnRadioButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {//程序设为客户端
combo.setEnabled(true);
combo_1.setEnabled(false);
button.setText("连接网络");
}
});
btnRadioButton_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {//程序设为服务器
combo.setEnabled(false);
combo_1.setEnabled(true);
button.setText("开始监听");
}
});
btnRadioButton_2.addSelectionListener(new SelectionAdapter() {//程序设为UDP
@Override
public void widgetSelected(SelectionEvent e) {
combo.setEnabled(true);
combo_1.setEnabled(true);
button.setText("开启UDP");
text_4.setEditable(true);
}
});
}
public String getIP(){//获取本地IP
try {
InetAddress inetaddress=InetAddress.getLocalHost();
localIP = inetaddress.getHostAddress();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return localIP;
} public void sendmessage(String s) throws IOException{
byte[]buf=s.getBytes();
// out.write(buf);
}
class client implements Runnable{
InputStream in;
OutputStream out;
String ip;
public void setIp(String ip) {
this.ip = ip;
}
public void setPort(int port) {
this.port = port;
}
int port;
@Override
public void run() {
// TODO Auto-generated method stub
try {
client_socket=new Socket(ip, port);
in=client_socket.getInputStream();
out=client_socket.getOutputStream();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
while((in.read())!=-1)
{
try{
byte[]buf=new byte[25];
in.read(buf);
String str=new String(buf);
text_4.append("\n服务器说:"+str+"\r\n");
in.reset();
Thread.sleep(1000);
}
catch(IOException e1){} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void send(String s) throws IOException{
byte[]buf=s.getBytes();
out.write(buf);
}
public void close(){
System.exit(0);
}
}
}
请对比下10楼的客户端,说明一下为什么同样的循环,一处正常运行,一处没响应,谢谢
ServerSocket可是一个珍贵的资源,没必要每开个线程,就给创建一次,太浪费了,你的服务器端也受不了!在类中加个构造方法,ServerSocket对象只创建一次够了
public Server(){
server=new ServerSocket(port);
}另外,将run()方法中的
server=new ServerSocket(port); 这一语句给去掉。