我用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){} 

解决方案 »

  1.   

    具体原因不太明白,但有可能是以下原因造成的,
    1.循环中动态分配空间 byte[]buf=new byte[256];
    2.in.read会阻塞,如果客户端每次发的正好是256还好,否则就会阻塞
      

  2.   

    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);你这个无限循环new了无限个String:String str=new String(buf); 
      

  3.   

    呃,新手,使用eclipse怎么检查内存?用断点的话停在readline那里就没反应了,直到有输入才动,但实际使用时除了我的输入,应该还会读取一些与服务器连接的信息吧?要不不至于近乎死机啊
      

  4.   

    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(); 

    }
      

  5.   

    难道同样一段代码,用swing运行就没事,用swt加线程就完蛋了?
      

  6.   

    整体代码:
    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楼的客户端,说明一下为什么同样的循环,一处正常运行,一处没响应,谢谢
      

  7.   


    ServerSocket可是一个珍贵的资源,没必要每开个线程,就给创建一次,太浪费了,你的服务器端也受不了!在类中加个构造方法,ServerSocket对象只创建一次够了
    public Server(){
        server=new ServerSocket(port); 
    }另外,将run()方法中的
    server=new ServerSocket(port); 这一语句给去掉。
      

  8.   

    查到资料了,之所以不好使是因为涉及到swt线程处理的问题,谢谢大家了