聊天工具小模型

今天开始自己学习java后第一个小项目的编写——“一个小型的聊天窗口互动小模型”,从昨天晚上开始看有关内容,今天早晨继续,算是完成了最初步的一些工作...现在来做一个小小的总结:

Chat0.1版本: 仅仅是new出来一个Frame的窗口,作为Client端;
Chat0.2版本: 在此Frame窗口内添加了TextFiled和TextArea,完善了Client端窗口的搭建。
Chat0.3版本: 仅仅添加了一个匿名类完成对Client端的关闭工作。
Chat0.4版本: 完成将TextField中输入的内容,显示到TextArea中的功能。

在这里,我将这4个版本合在一起,称为MyChat0.1版本:
import java.awt.*;
import java.awt.event.*;


public class ChatClient extends Frame{

TextField tfTxt = new TextField();
TextArea taContent = new TextArea();

public static void main(String[] args) {
new ChatClient().launchFrame();
}

public void launchFrame() {
setLocation(400, 300);
setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
// taContent.setBackground(Color.LIGHT_GRAY);
pack();
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
setVisible(false);
System.exit(-1);
}

});
tfTxt.addActionListener(new TFListener());
setVisible(true);
}

private class TFListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String s = tfTxt.getText().trim();
taContent.setText(s);
tfTxt.setText("");
}

}
}


得到结果为:

[img]http://dl.iteye.com/upload/attachment/352564/88ca7a6f-e69b-3d30-a4ef-7e6675d86b6f.jpg[/img]


Chat0.5版本: 增加了Server端,实现Sever端的基本功能。
Chat0.6版本: 在Clint端添加方法Connect(),实现和Server端建立联接的功能;并在实现ActionListener接口时添加代码,将Client端TextField中输入的内容在Server端输出;在Server端添加必要代码,接收Client端传来的数据。

这里,我将这两个版本合并在一起,称为MyChat0.2版本:
ChatServer.java为:
import java.io.*;
import java.net.*;
public class ChatServer {

public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(8888);
while (true) {
Socket s = ss.accept();
System.out.println("a client connected!");
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = dis.readUTF();
System.out.println(str);
dis.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


ChatClient.java为:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;


public class ChatClient extends Frame{

Socket s = null;
TextField tfTxt = new TextField();
TextArea taContent = new TextArea();

public static void main(String[] args) {
new ChatClient().launchFrame();
}

public void launchFrame() {
setLocation(400, 300);
setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
// taContent.setBackground(Color.LIGHT_GRAY);
pack();
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
setVisible(false);
System.exit(-1);
}

});
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
}

private void connect() {
try {
s = new Socket("127.0.0.1", 8888);
System.out.println("connected!");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private class TFListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str = tfTxt.getText().trim();
taContent.setText(str);
tfTxt.setText("");

try {
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(str);
dos.flush();
dos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

}
}


在Client窗口输入"FIRST",运行结果为:

[img]http://dl.iteye.com/upload/attachment/352572/9772ed0b-bb0c-3e4f-a0d2-4494bef807aa.jpg[/img]

但是当第二次在Client窗口输入"SECOND”时,程序抛出异常,如图:

[img]http://dl.iteye.com/upload/attachment/352576/f1e7c3e9-ef6c-39a5-a244-628a1835d47a.jpg[/img]
异常显示提示:Socket已经关闭,检查程序,发现在ChatClient.java里有dos.close()语句关闭了Socket,应去掉此语句。将在MyChat0.3中改进。


Chat0.7版本同0.6,嘿嘿,貌似0.6版本改太多了。。。
Chat0.8版本: 在ChatClient.java里注释掉dos.close()语句,将DataOutputStream dos变为外部类成员变量,增加disconnect()方法;在ChatServer.java里修改while(true)语句。
在这里,我将Chat0.8版本修改的内容分开,在我的MyChat0.3版本里,实现Chat0.8版本分号前的变化。在MyChat0.4版本里,实现Chat0.8版本分号后的变化:
ChatServer.java同0.2版本,ChatClient.java为:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;


public class ChatClient extends Frame{

Socket s = null;

DataOutputStream dos;

TextField tfTxt = new TextField();

TextArea taContent = new TextArea();

public static void main(String[] args) {
new ChatClient().launchFrame();
}

public void launchFrame() {
setLocation(400, 300);
setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
// taContent.setBackground(Color.LIGHT_GRAY);
pack();
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
setVisible(false);
disconnect();
System.exit(-1);
}

});
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
}

private void connect() {
try {
s = new Socket("127.0.0.1", 8888);
dos = new DataOutputStream(s.getOutputStream());
System.out.println("connected!");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private void disconnect() {
try {
dos.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private class TFListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str = tfTxt.getText().trim();
taContent.setText(str);
tfTxt.setText("");

try {
dos.writeUTF(str);
dos.flush();
// dos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

}
}


最后得到结果: 解决了0.2版中Client一方不能多次输入的问题,但是在Server端出现新问题,即在Client端第二次及以后输入的数据在Server端无法显示。这是因为Server端String str = dis.readUTF();为阻塞式语句,代码会一直停在那里等待read,不能回到之前代码ServerSocket ss = new ServerSocket(8888);和DataInputStream dis = new DataInputStream(s.getInputStream());MyCaht0.4版本将通过修改while(true)的方式解决这一问题。

MyChat0.4版本ChatClient.java同0.3版本,ChatServer.java代码如下:
import java.io.*;
import java.net.*;
public class ChatServer {

public static void main(String[] args) {
boolean started = false;
try {
ServerSocket ss = new ServerSocket(8888);
started = true;
while (started) {
boolean bConnected = false;
Socket s = ss.accept();
System.out.println("a client connected!");
bConnected = true;
DataInputStream dis = new DataInputStream(s.getInputStream());
while (bConnected) {
String str = dis.readUTF();
System.out.println(str);
}
dis.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

得到结果如图:

[img]http://dl.iteye.com/upload/attachment/352620/bc44e519-c10c-3927-9fa8-7daa9d2128c9.jpg[/img]
解决了之前两个版本的小BUG。
但是,当关闭窗口时,系统会抛出如下所示的异常:
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at ChatServer.main(ChatServer.java:17)

这是因为
Server端String str = dis.readUTF()语句造成的!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值