客户端:
package com;import java.awt.TextArea;
public class ChatClient implements Runnable{
private static Text text;
private static Text txt_Area;
Socket s = null; //一个插座
DataOutputStream dos = null; //向服务器写入数据
DataInputStream dis=null; //从服务器读数据 Display display;
Shell shell; private boolean bConnected=false; //是否连接 //Thread tRecv=new Thread(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 void th(){ Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(bConnected){
String str=dis.readUTF();
System.out.println("数据接收成功");
txt_Area.append(str+'\n');
}
} catch (Exception e) {
System.out.println("退出了,bye!");
}
}
});
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
th();
} catch (Exception e) {
System.exit(0);
}
}
}}
服务器端
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();
}
}
}
}
}
哪位大哥可以帮我解决啊 搞了两天了 都不行 客户端一开就卡死了 怎么办啊
package com;import java.awt.TextArea;
public class ChatClient implements Runnable{
private static Text text;
private static Text txt_Area;
Socket s = null; //一个插座
DataOutputStream dos = null; //向服务器写入数据
DataInputStream dis=null; //从服务器读数据 Display display;
Shell shell; private boolean bConnected=false; //是否连接 //Thread tRecv=new Thread(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 void th(){ Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(bConnected){
String str=dis.readUTF();
System.out.println("数据接收成功");
txt_Area.append(str+'\n');
}
} catch (Exception e) {
System.out.println("退出了,bye!");
}
}
});
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
th();
} catch (Exception e) {
System.exit(0);
}
}
}}
服务器端
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();
}
}
}
}
}
哪位大哥可以帮我解决啊 搞了两天了 都不行 客户端一开就卡死了 怎么办啊
解决方案 »
- 怎么不字符串的内容作为另外一个类的引用
- 零基础能学JAVA吗?
- 免费下载
- 在相应的 try 语句主体中不能抛出异常的问题
- 如何使用java实现包含checkbox的表格。
- java调用dll文件,堆栈崩溃溢出的问题
- 各位高手请帮我一个忙吧!!
- 谁有Weblogic 6.1的资料, E文的或者6.0的也行!!!!求助!!
- 谁有JBuilder4的Licensing,帮忙告诉我一下,我买的盗版碟不正版。
- CharBuffer的clear()小问题
- 求助:JAVA表格的问题
- Exception in thread "main" java.lang.OutOfMemoryError: Java heap space,怎么办
在read, write前后各写一句输出根据输出情况判断大致问题所在
Display.getDefault().asyncExec 明显是会导致不停的new thread。
不死就怪了。
接80分...private void th(){Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(bConnected){
String str=dis.readUTF();
System.out.println("数据接收成功");
txt_Area.append(str+'\n');
}
} catch (Exception e) {
System.out.println("退出了,bye!");
}
}
});
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
th();
} catch (Exception e) {
System.exit(0);
}
}}
因为:asyncExec中执行的线程会阻塞GUI主线程。虽然和界面死没直接关系,但是Server还有点问题,楼主需要细改。从clients中移除Client对象和终止该客户端对应的Server端线程是两码事...
这个方法明显是调用runable实例参数的start。就完事。不响应的原因是正是不阻塞然后一个死循环导致的。
while(true){}楼主的client本身就实现了一个runable.
所以把通信的事情放在run里执行也是很正确的。th()方法里可以直接写。
String str=dis.readUTF();
System.out.println("数据接收成功");
txt_Area.append(str+'\n');
}
} catch (Exception e) {
System.out.println("退出了,bye!");
}
syncExec阻塞的是非主线程,asyncExec不阻塞的也是非主线程。不多说,贴5楼所说的修改方法的明细代码(客户端的run方法)如下: private String msg; @Override
public void run() {
while (true) {
try {
if (bConnected) {
msg = dis.readUTF();
System.out.println("数据接收成功");
}
} catch (Exception e) {
System.out.println("退出了,bye!");
break;
}
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
txt_Area.append(msg + '\n');
}
});
try {
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
} }
因为线程体中代码少,上面改过的代码中用asyncExec或syncExec效果是一样的。
另外:查了下swt的api syncExec 里面说The thread which calls this method is suspended until the runnable completes.
aSyncExec 里面说The caller of this method continues to run in parallel, and is not notified when the runnable has completed另外:我的回复里笔误,是当前线程。
at org.eclipse.swt.SWT.error(SWT.java:3563)
at org.eclipse.swt.SWT.error(SWT.java:3481)
at org.eclipse.swt.SWT.error(SWT.java:3452)
at org.eclipse.swt.widgets.Display.error(Display.java:1137)
at org.eclipse.swt.widgets.Display.asyncExec(Display.java:630)
at com.ChatClient$RecvThread.run(ChatClient.java:168)
at java.lang.Thread.run(Thread.java:619)
8楼得改法我试了 首先在每个客户端不会出现某一个客户端发的信息
然后关闭服务器还报错为啥啊
退出程序的时候如果直接用System.exit()就看不到这样的异常了。