客户端:
package com;import java.awt.TextArea;public class ChatClient{
protected static Text text;
protected static Text txt_Area;
Socket s = null;                 //一个插座
DataOutputStream dos = null;     //向服务器写入数据
DataInputStream dis=null;        //从服务器读数据 public Display display;
public Shell shell; public boolean bConnected=false;   //是否连接 Thread tRecv=new Thread(new RecvThread());   //为客户端开一个线程
//RecvThread tRecv=new RecvThread(); public static void main(String[] args) {
new ChatClient().launchFrame();
}
public void launchFrame(){  //初始化窗体
display = Display.getDefault(); //
shell = new Shell();               //存在应用程序的其他控件
shell.setToolTipText("\u804A\u5929\u7CFB\u7EDF\u5BA2\u6237\u7AEF\r\n");
shell.setImage(SWTResourceManager.getImage("F:\\\u56FE\u7247\\\u5F6C\u5F6C\\\u5F6C\u5F6C\u7ED9\u6211\u7684.jpg"));
shell.setSize(450, 342);
shell.setText("\u804A\u5929\u5BA2\u6237\u7AEF");
shell.setLayout(null); Button btn_Send = new Button(shell, SWT.NONE);
btn_Send.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
try{
send();
}catch(Exception e2){
e2.printStackTrace();
}
}
});
btn_Send.setBounds(340, 276, 68, 22);
btn_Send.setText("\u53D1\u9001"); text = new Text(shell, SWT.BORDER);
text.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
try {
keypressed(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
text.setBounds(22, 219, 386, 51); txt_Area = new Text(shell, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
txt_Area.setBounds(24, 10, 388, 203); shell.open();
shell.layout(); text.forceFocus(); connect();   //连接服务器 tRecv.start();                                      //为每个客户端 开一个线程

//new Thread(this).start();        //开始线程
txt_Area.append("多线程已经开启");
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
} } disconnect();                                      //连接关闭
display.dispose();                                  //关闭窗体   
} public void keypressed(KeyEvent e) throws Exception{
if(e.keyCode==13){
send();    
}
}
public void send(){   //发送
String str = text.getText().trim();
txt_Area.setText(txt_Area.getText()+str+'\n');
text.setText(""); try {
// System.out.println(s);
dos.writeUTF(str);                             //发送数据
dos.flush();                                   //推一把
//dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void connect(){       //连接
try {
s = new Socket("127.0.0.1",3333);
dos = new DataOutputStream(s.getOutputStream());//往服务器写
dis = new DataInputStream(s.getInputStream());    //从服务器读
System.out.println("connected!");
bConnected=true;
txt_Area.append("已经连接上服务器"+'\n');
}catch (Exception e) {
e.printStackTrace();
}
} public void disconnect() {    //结束
try {
dos.close();           
dis.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private class RecvThread implements Runnable {  
@Override
public void run() {
//display.getDefault().asyncExec(new Runnable(){
// @Override
//public void run() {
try{

while(bConnected){
String str=dis.readUTF();

System.out.println("我读到了数据是"+str);
txt_Area.append(str+'\n');
}
} catch (SocketException e) {
System.out.println("退出了,bye!");
} catch (EOFException e) {
System.out.println("推出了,bye - bye!");
} catch (IOException e) {
e.printStackTrace();
}

// }
//});  
}
}


}服务器:
package com;
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
boolean started = false;
ServerSocket ss =null;

List<Client> clients=new ArrayList<Client>(); public static void main(String[] args) {
new ChatServer().start();
} public void start(){
try {
ss = new ServerSocket(3333);        //开放一个端口
started=true;                       //开始处理
}catch(BindException e){
System.out.println("端口使用中");
System.out.println("请关掉相关程序并重新运行服务器!");
System.exit(0);
}catch(IOException e){
e.printStackTrace();
} try{
while(started){                     //端口开放
Socket s=ss.accept();            //接受数据
Client c=new Client(s);         //传递参数
System.out.println("a client connected!");     //bConnected=true已经连接
new Thread(c).start();              //开始执行线程
clients.add(c);                    //执行完线程增加到clients中
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
ss.close();
}catch(IOException  e){
e.printStackTrace();
}
} }
class Client implements Runnable{
private Socket s;                          //每一个线程的接受数据
private DataInputStream dis =null;               //从客户端得到数据
private DataOutputStream dos=null;               //向客户端写出数据

private boolean bConnected = false;             //单独的一个线程的标记 ,是否开启 public void send(String str){                    //给每个客户端发送数据
try{
dos.writeUTF(str);
}catch(IOException e){
clients.remove(this);
System.out.println("对方退出了!我从List里面去掉了!");
}
}
public Client(Socket s){
this.s=s;
try{
dis= new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
bConnected=true;                          //已经连接 }catch(IOException e){
e.printStackTrace();
}
} @Override
public void run() {
try{
while(bConnected) {                       //当连接的时候
String str = dis.readUTF();            //阻塞世 傻傻的等待,每次接受一个就卡在这里了
System.out.println(str);
for(int i=0;i<clients.size();i++){
                         Client c=clients.get(i);
                         c.send(str);                      //把读到的数据发送出去
                         
}
}
} catch (EOFException e) {
System.out.println("客户端已经关闭!");     //客户端关闭的时候提示  已经结束
}catch(IOException e){
e.printStackTrace();
}finally{
try {
if(dis!=null) dis.close();            //最后关闭文件流,Socket
if(dos!=null) dos.close();
if(s!=null) s.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
调试了三天了都不行  用SWT写的   这个多线程问题好纠结啊 ,服务器端代码没问题,主要是客户端的SWT多线程问题
应该怎么改才能让其不报错啊,QQ30513207  哪位大虾有空帮我改改哈

解决方案 »

  1.   

    修改好了 
    System.out.println("我读到了数据是" + str);
    // txt_Area.append(str + '\n');
    txt_Area.setText(txt_Area.getText()+" "+str);Text的append方法换成 setText了批评你一下,你发的代码包都没有导入,累死我了
      

  2.   

    http://topic.csdn.net/u/20110708/21/b8f5f4ef-8527-48e6-9971-cb32508a13f4.html
    我就不再贴了,请楼主到那边看去。
      

  3.   

    这边的程序是因为readUTF阻塞了,反而看不到后面的异常了。(因祸得福?)
    SWT多线程必须用到asyncExec或syncExec,这倒是毫无疑问的。