简单的java聊天程序

天边的云 2011-08-26 05:30:30
小弟刚学完java基础,练练手就做了一个特别简单的聊天程序,源代码如下:
import java.net.*;
import java.awt.*;
import java.awt.event.*;
public class Receive {
Frame f=new Frame("聊天室");
TextField tfIP=new TextField(15);
TextArea lst=new TextArea();
Label lb=new Label("IP");
DatagramSocket ds;
TextField tfData=new TextField(20);
Button bt=new Button("send");
Button bt2=new Button("Content can't for empty");//定义模态显示
Dialog dlg=new Dialog(f,"消息提示",true);



public static void main(String args[]){

new Receive();//调用构造函数初始化
}



public Receive(){
try{
ds=new DatagramSocket(8087);
}catch(Exception ex){
ex.printStackTrace();
}

//设置线程监听对方发送的内容
new Thread(new Runnable(){
public void run(){

byte buf[]=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
while(true){
try{
ds.receive(dp);
lst.append("对方(来自"+dp.getAddress().getHostAddress()+",接口:"+dp.getPort()+") "+"当前时间:"+"\n"+new String(buf,0,dp.getLength())+"\n");
}catch(Exception e){
e.printStackTrace();
}
}
}
}).start();
init1();
}


public void init1(){
f.setSize(400,400);//设置容器的大小
f.add(lst);
//添加组件,布置布局
Panel p1=new Panel();
Panel p2=new Panel();
Panel p3=new Panel();
p1.setLayout(new BorderLayout());
p2.setLayout(new BorderLayout());
p3.setLayout(new BorderLayout());
p1.add("West",lb);
p1.add("East",tfIP);
p2.add("West",bt);
p2.add("East",tfData);
p3.add("West",p1);
p3.add("East",p2);
f.add("South",p3);

dlg.setLayout(new FlowLayout());
dlg.add(bt2);
dlg.setBounds(0, 0, 200, 150);//设置提示框的大小

f.setVisible(true);//让容器可显示
f.setResizable(false);//不可改变容器大小

//关闭窗口事件
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
ds.close();
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
//触发按钮事件
bt.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ex){
byte[]buf;
buf=tfData.getText().getBytes();
if(buf.length!=0){
try{
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName(tfIP.getText()),8088);
ds.send(dp);
tfData.setText("");
lst.append("自己:"+"\n"+new String(buf)+"\n");//new String(dp.getData());
}catch(Exception e){
e.printStackTrace();
}
}else{//设置成为模态显示并其可现
dlg.setModal(true);
dlg.setVisible(true);
}
}
});
//模态显示按钮的触发事件
bt2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
dlg.dispose();
}
});
//输入文本框的触发事件
tfData.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){

byte[]buf;
buf=e.getActionCommand().getBytes();
if(buf.length!=0){
try{
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName(tfIP.getText()),8088);
ds.send(dp);
((TextField)e.getSource()).setText("");
lst.append("自己:"+"\n"+new String(buf)+"\n");//new String(dp.getData());
}catch(Exception ex){
ex.printStackTrace();
}
}else{
dlg.setModal(true);
dlg.setVisible(true);
}
}
});
}
}

把上面的代码在复制一个,改变一下端口,就可以实现简单的聊天了,但还有一些功能没有实现,还请各位大虾指点一二。
未能实现的功能:双方发送的内容所显示的动态时间;发送框在程序刚开始运行的时候,光标没在发送框;发送按钮不能显示中文,不知道怎么解决这个中文乱码
还请大家帮忙啊!
...全文
2429 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
softneo 2014-04-03
  • 打赏
  • 举报
回复
真迷惑人。。。
softneo 2014-04-03
  • 打赏
  • 举报
回复
怎么用啊,擦,只能发不能收!
鱼肉烧 2013-08-16
  • 打赏
  • 举报
回复
搞错了,应该是192行,第192行那里,如果发送信息为空,则弹出“无效信息”,但是直接return的话,就没有关闭发送资源,端口还在占用着,之后发信息就会出现“本地发送端口已被使用”。所以应该在192行后面加上ds.close()
鱼肉烧 2013-08-16
  • 打赏
  • 举报
回复
楼主,我发现了一点问题,第186行那里,如果发送信息为空,则弹出“无效信息”,但是直接return的话,就没有关闭发送资源,端口还在占用着,之后发信息就会出现“本地发送端口已被使用”。所以应该在186行后面加上ds.close()
风尘中国 2011-08-27
  • 打赏
  • 举报
回复
感谢楼主和楼上哥们的代码,不过楼上是用AWT做的,我改成SWING实现,能够避免AWT带来的中文乱码问题
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class PointToPointUDPChat {
JFrame f = new JFrame("聊天室");

JLabel lbRemoteIP = new JLabel("目标IP");// 对方IP
JLabel lbRemotePort = new JLabel("目标端口");
JLabel lbLocalSendPort = new JLabel("本地发送端口");
JLabel lbLocalReceivePort = new JLabel("本地接收端口");

JTextField tfRemoteIP = new JTextField(15);// 要发送数据的目标IP
JTextField tfRemotePort = new JTextField(15);// 要发送数据的目标端口
JTextField tfLocalSendPort = new JTextField(15);// 使用此端口发送数据
JTextField tfLocalReceivePort = new JTextField(15);// 使用此端口发送数据

String remoteIP = null;
int remotePort = 0;
int localSendPort = 0;
int localReceivePort = 0;
JTextArea allChatContent = new JTextArea();

JTextField sendChatContent = new JTextField(20);

JButton connect = new JButton("连接");
JButton disConnect = new JButton("断开");
JButton bt = new JButton("发送");
Thread receiveThread = null;//利用start和stop控制是否接收消息

public PointToPointUDPChat() {
initFrame();
}

public static void main(String args[]) {
new PointToPointUDPChat();
}

// 外观布局,添加事件响应
public void initFrame() {// //////

f.setSize(400, 500);// 设置容器的大小
f.setLayout(new BorderLayout());
JPanel p = new JPanel();
JPanel p2 = new JPanel();

// 添加组件,布置布局
p.setLayout(new GridLayout(5, 5));
p.add(lbRemoteIP);
p.add(tfRemoteIP);
p.add(lbRemotePort);
p.add(tfRemotePort);
p.add(lbLocalSendPort);
p.add(tfLocalSendPort);
p.add(lbLocalReceivePort);
p.add(tfLocalReceivePort);
p.add(connect);
p.add(disConnect);

f.add("North", p);
connect.addActionListener(new ActionListener() {//连接按钮事件
public void actionPerformed(ActionEvent e) {
try{
remoteIP = tfRemoteIP.getText();
remotePort = Integer.parseInt(tfRemotePort.getText());
localSendPort = Integer.parseInt(tfLocalSendPort
.getText());
localReceivePort = Integer.parseInt(tfLocalReceivePort
.getText());
}catch (Exception exception) {
prompt("连接信息不能为空或格式错误");
return;
}
if (!checkIP(remoteIP)) {
prompt("目标IP设置错误");
return;
}
if (!checkPort(remotePort)) {
prompt("目标端口设置错误");
return;
}
if (!checkPort(localSendPort)) {
prompt("本地发送端口设置错误");
return;
}
if (!checkPort(localReceivePort)) {
prompt("本地接收端口设置错误");
return;
}
prompt("连接成功");
tfRemoteIP.setEditable(false);
tfRemotePort.setEditable(false);
tfLocalReceivePort.setEditable(false);
tfLocalSendPort.setEditable(false);
receiveMessage();
}
});

disConnect.addActionListener(new ActionListener() {//断开按钮事件
public void actionPerformed(ActionEvent e) {
tfRemoteIP.setEditable(true);
tfRemotePort.setEditable(true);
tfLocalReceivePort.setEditable(true);
tfLocalSendPort.setEditable(true);
tfLocalReceivePort.setText("");
tfLocalSendPort.setText("");
tfRemoteIP.setText("");
tfRemotePort.setText("");

remoteIP = null;
remotePort = 0;
localSendPort = 0;
localReceivePort = 0;
receiveThread.stop();
prompt("断开成功");
}
});

f.add("Center", allChatContent);

p2.setLayout(new FlowLayout());
p2.add(bt);
p2.add(sendChatContent);// ///p2面板添加发送按钮和要发送的内容
f.add("South", p2);

f.setLocationRelativeTo(null);//设置居中
f.setVisible(true);// 让容器可显示
f.setResizable(false);// 不可改变容器大小

// 关闭窗口事件
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.setVisible(false);
f.dispose();
System.exit(0);
}
});

// //////触发发送按钮事件
bt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMessage();
}

});
// 模态显示按钮的触发事件

// 输入文本框的触发事件
sendChatContent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMessage();
}
});



}

// 发送数据
public void sendMessage() {//
//定义ds
DatagramSocket ds = null;
try {
ds = new DatagramSocket(localSendPort);
} catch (SocketException e1) {
prompt("本地发送端口已被使用");
return;
}
//设置发送信息
String sendMessage = sendChatContent.getText().trim();
if (sendMessage.equals("")) {
prompt("无效信息");
return;
}
byte[] buf = sendMessage.getBytes();// /////获得要发送的数据

//设置接收数据的远程IP地址
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getByName(tfRemoteIP.getText().trim());
} catch (UnknownHostException e) {
prompt("非法远程IP地址");
return;
}

//发送
DatagramPacket dp = new DatagramPacket(buf, 0, buf.length, inetAddress,
remotePort);
try {
ds.send(dp);
} catch (IOException e) {
prompt("网络故障,发送失败");
return;
}
sendChatContent.setText("");// //发送完数据,发送框重置为空

allChatContent.append(new java.text.SimpleDateFormat(
"yy-MM-dd HH:mm:ss").format(new Date())
+ " send to Remote("
+ dp.getAddress()
+ " "
+ dp.getPort()
+ ") :\n");
allChatContent.append(sendMessage + "\n");
ds.close();
}

// 接收数据
class MyRunnable implements Runnable {
byte buf[] = new byte[1024];
DatagramSocket ds = null;
DatagramPacket dp = null;

public void run() {
dp = new DatagramPacket(buf, 0, 1024);
try {
ds = new DatagramSocket(localReceivePort);
} catch (SocketException e1) {
prompt("本地接收端口已被使用");
return;
}
while (true) {
try {
ds.receive(dp);
} catch (IOException e) {
ds.close();
e.printStackTrace();
}
String receiveMessage = new String(dp.getData(), 0, dp
.getLength());
allChatContent.append(new java.text.SimpleDateFormat(
"yy-MM-dd HH:mm:ss").format(new Date())//
+ " from remote("
+ dp.getAddress().getHostAddress()
+ " " + dp.getPort() + ") :\n" + receiveMessage + "\n");
sendChatContent.setCaretPosition(sendChatContent.getText()
.length());

}
}

}

public void receiveMessage() {//
receiveThread = new Thread(new MyRunnable());
receiveThread.start();
}

//异常处理
public void prompt(String promptMessage) {
JOptionPane.showConfirmDialog(null, promptMessage, "友情提示",
JOptionPane.WARNING_MESSAGE);
}

public boolean checkPort(int port) {
return String.valueOf(port).matches("\\d+") && port > 1024
&& port <= 65535;

}

public boolean checkPort(String port) {
return port.matches("\\d+") && Integer.parseInt(port) > 1024
&& Integer.parseInt(port) <= 65535;

}

public boolean checkIP(String ip) {
java.util.regex.Matcher m = Pattern.compile(
"(\\d{1,3}).(\\d{1,3}).(\\d{1,3}).(\\d{1,3})").matcher(ip);
if (m.find()) {
for (int i = 1; i <= 4; i++)
if (Integer.parseInt(m.group(i)) < 0
|| Integer.parseInt(m.group(i)) > 255)
return false;
return true;
}
return true;
}

}
天边的云 2011-08-27
  • 打赏
  • 举报
回复
谢谢大家伙的帮助了
打油的程序员 2011-08-27
  • 打赏
  • 举报
回复
打油的程序员 2011-08-27
  • 打赏
  • 举报
回复
测试结果:
http://hi.csdn.net/attachment/201108/26/5180698_131438555672JC.jpg

原来.bmp图片上传不到空间,除了改后缀名,还有什么办法?
打油的程序员 2011-08-27
  • 打赏
  • 举报
回复
稍微修改了一下


import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;

public class PointToPointUDPChat {
Frame f = new Frame("聊天室");

Label lbRemoteIP = new Label("目标IP");// 对方IP
Label lbRemotePort = new Label("目标端口");
Label lbLocalSendPort = new Label("本地发送端口");
Label lbLocalReceivePort = new Label("本地接收端口");

TextField tfRemoteIP = new TextField(15);// 要发送数据的目标IP
TextField tfRemotePort = new TextField(15);// 要发送数据的目标端口
TextField tfLocalSendPort = new TextField(15);// 使用此端口发送数据
TextField tfLocalReceivePort = new TextField(15);// 使用此端口发送数据

String remoteIP = null;
int remotePort = 0;
int localSendPort = 0;
int localReceivePort = 0;
TextArea allChatContent = new TextArea();

TextField sendChatContent = new TextField(20);

Button connect = new Button("连接");
Button disConnect = new Button("断开");
Button bt = new Button("发送");
Thread receiveThread = null;//利用start和stop控制是否接收消息

public PointToPointUDPChat() {
initFrame();
}

public static void main(String args[]) {
new PointToPointUDPChat();
}

// 外观布局,添加事件响应
public void initFrame() {// //////

f.setSize(400, 500);// 设置容器的大小
f.setLayout(new BorderLayout());
Panel p = new Panel();
Panel p2 = new Panel();

// 添加组件,布置布局
p.setLayout(new GridLayout(5, 5));
p.add(lbRemoteIP);
p.add(tfRemoteIP);
p.add(lbRemotePort);
p.add(tfRemotePort);
p.add(lbLocalSendPort);
p.add(tfLocalSendPort);
p.add(lbLocalReceivePort);
p.add(tfLocalReceivePort);
p.add(connect);
p.add(disConnect);

f.add("North", p);
connect.addActionListener(new ActionListener() {//连接按钮事件
public void actionPerformed(ActionEvent e) {
try{
remoteIP = tfRemoteIP.getText();
remotePort = Integer.parseInt(tfRemotePort.getText());
localSendPort = Integer.parseInt(tfLocalSendPort
.getText());
localReceivePort = Integer.parseInt(tfLocalReceivePort
.getText());
}catch (Exception exception) {
prompt("连接信息不能为空或格式错误");
return;
}
if (!checkIP(remoteIP)) {
prompt("目标IP设置错误");
return;
}
if (!checkPort(remotePort)) {
prompt("目标端口设置错误");
return;
}
if (!checkPort(localSendPort)) {
prompt("本地发送端口设置错误");
return;
}
if (!checkPort(localReceivePort)) {
prompt("本地接收端口设置错误");
return;
}
prompt("连接成功");
tfRemoteIP.setEditable(false);
tfRemotePort.setEditable(false);
tfLocalReceivePort.setEditable(false);
tfLocalSendPort.setEditable(false);
receiveMessage();
}
});

disConnect.addActionListener(new ActionListener() {//断开按钮事件
public void actionPerformed(ActionEvent e) {
tfRemoteIP.setEditable(true);
tfRemotePort.setEditable(true);
tfLocalReceivePort.setEditable(true);
tfLocalSendPort.setEditable(true);
tfLocalReceivePort.setText("");
tfLocalSendPort.setText("");
tfRemoteIP.setText("");
tfRemotePort.setText("");

remoteIP = null;
remotePort = 0;
localSendPort = 0;
localReceivePort = 0;
receiveThread.stop();
prompt("断开成功");
}
});

f.add("Center", allChatContent);

p2.setLayout(new FlowLayout());
p2.add(bt);
p2.add(sendChatContent);// ///p2面板添加发送按钮和要发送的内容
f.add("South", p2);

f.setVisible(true);// 让容器可显示
f.setResizable(false);// 不可改变容器大小

// 关闭窗口事件
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.setVisible(false);
f.dispose();
System.exit(0);
}
});

// //////触发发送按钮事件
bt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMessage();
}

});
// 模态显示按钮的触发事件

// 输入文本框的触发事件
sendChatContent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMessage();
}
});



}

// 发送数据
public void sendMessage() {//
//定义ds
DatagramSocket ds = null;
try {
ds = new DatagramSocket(localSendPort);
} catch (SocketException e1) {
prompt("本地发送端口已被使用");
return;
}
//设置发送信息
String sendMessage = sendChatContent.getText().trim();
if (sendMessage.equals("")) {
prompt("无效信息");
return;
}
byte[] buf = sendMessage.getBytes();// /////获得要发送的数据

//设置接收数据的远程IP地址
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getByName(tfRemoteIP.getText().trim());
} catch (UnknownHostException e) {
prompt("非法远程IP地址");
return;
}

//发送
DatagramPacket dp = new DatagramPacket(buf, 0, buf.length, inetAddress,
remotePort);
try {
ds.send(dp);
} catch (IOException e) {
prompt("网络故障,发送失败");
return;
}
sendChatContent.setText("");// //发送完数据,发送框重置为空

allChatContent.append(new java.text.SimpleDateFormat(
"yy-MM-dd HH:mm:ss").format(new Date())
+ " send to Remote("
+ dp.getAddress()
+ " "
+ dp.getPort()
+ ") :\n");
allChatContent.append(sendMessage + "\n");
ds.close();
}

// 接收数据
class MyRunnable implements Runnable {
byte buf[] = new byte[1024];
DatagramSocket ds = null;
DatagramPacket dp = null;

public void run() {
dp = new DatagramPacket(buf, 0, 1024);
try {
ds = new DatagramSocket(localReceivePort);
} catch (SocketException e1) {
prompt("本地接收端口已被使用");
return;
}
while (true) {
try {
ds.receive(dp);
} catch (IOException e) {
ds.close();
e.printStackTrace();
}
String receiveMessage = new String(dp.getData(), 0, dp
.getLength());
allChatContent.append(new java.text.SimpleDateFormat(
"yy-MM-dd HH:mm:ss").format(new Date())//
+ " from remote("
+ dp.getAddress().getHostAddress()
+ " " + dp.getPort() + ") :\n" + receiveMessage + "\n");
sendChatContent.setCaretPosition(sendChatContent.getText()
.length());

}
}

}

public void receiveMessage() {//
receiveThread = new Thread(new MyRunnable());
receiveThread.start();
}

//异常处理
public void prompt(String promptMessage) {
JOptionPane.showConfirmDialog(null, promptMessage, "友情提示",
JOptionPane.WARNING_MESSAGE);
}

public boolean checkPort(int port) {
return String.valueOf(port).matches("\\d+") && port > 1024
&& port <= 65535;

}

public boolean checkPort(String port) {
return port.matches("\\d+") && Integer.parseInt(port) > 1024
&& Integer.parseInt(port) <= 65535;

}

public boolean checkIP(String ip) {
java.util.regex.Matcher m = Pattern.compile(
"(\\d{1,3}).(\\d{1,3}).(\\d{1,3}).(\\d{1,3})").matcher(ip);
if (m.find()) {
for (int i = 1; i <= 4; i++)
if (Integer.parseInt(m.group(i)) < 0
|| Integer.parseInt(m.group(i)) > 255)
return false;
return true;
}
return true;
}

}


风尘中国 2011-08-26
  • 打赏
  • 举报
回复
我想问个问题,为什么采用UDP实现?
天边的云 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 d_east 的回复:]
LZ牛B.端口怎么改的?
[/Quote]
你看发送的时候是8088,而自己接受的是8087,8087是一个自己应用程序对外的接口,8088则是另外一个应用程序对外接口,要指定对方的接口,这样另外一方才能收到信息
天边的云 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 niuniu20008 的回复:]
看着有点累,lz要学习如何贴代码
[/Quote]
好像csdn的问题,我发布的时候看了看,但是一发布就成这个,当然我看见别人好像弄得格式挺好,会学习的
xiaomaoxiaomao11 2011-08-26
  • 打赏
  • 举报
回复
学习中
mhmxd 2011-08-26
  • 打赏
  • 举报
回复
发送按钮的字体改成宋体就是了。。
niuniu20008 2011-08-26
  • 打赏
  • 举报
回复
看着有点累,lz要学习如何贴代码
D_east 2011-08-26
  • 打赏
  • 举报
回复
LZ牛B.端口怎么改的?
小笨熊 2011-08-26
  • 打赏
  • 举报
回复
呵呵,lz不赖,加油
Java聊天程序 需求分析 2.1 业务需求 1. 与聊天室成员一起聊天。 2. 可以与聊天室成员私聊。 3. 可以改变聊天内容风格。 4. 用户注册(含头像)、登录。 5. 服务器监控聊天内容。 6. 服务器过滤非法内容。 7. 服务器发送通知。 8. 服务器踢人。 9. 保存服务器日志。 10.保存用户聊天信息。 2.2 系统功能模块 2.2.1 服务器端 1.处理用户注册 2.处理用户登录 3.处理用户发送信息 4.处理用户得到信息 5.处理用户退出 2.2.2 客户端 1.用户注册界面及结果 2.用户登录界面及结果 3.用户发送信息界面及结果 4.用户得到信息界面及结果 5.用户退出界面及结果 2.3 性能需求 运行环境:Windows 9x、2000、xp、2003,Linux 必要环境:JDK 1.5 以上 硬件环境:CPU 400MHz以上,内存64MB以上 3.1.2 客户端结构 ChatClient.java 为客户端程序启动类,负责客户端的启动和退出。 Login.java 为客户端程序登录界面,负责用户帐号信息的验证与反馈。 Register.java 为客户端程序注册界面,负责用户帐号信息的注册验证与反馈。 ChatRoom.java 为客户端程序聊天室主界面,负责接收、发送聊天内容与服务器端的Connection.java 亲密合作。 Windowclose 为ChatRoom.java的内部类,负责监听聊天室界面的操作,当用户退出时返回给服务器信息。 Clock.java 为客户端程序的一个小程序,实现的一个石英钟功能。 3. 2 系统实现原理 当用户聊天时,将当前用户名、聊天对象、聊天内容、聊天语气和是否私聊进行封装,然后与服务器建立Socket连接,再用对象输出流包装Socket的输出流将聊天信息对象发送给服务器端 当用户发送聊天信息时,服务端将会收到客户端用Socket传输过来的聊天信息对象,然后将其强制转换为Chat对象,并将本次用户的聊天信息对象添加到聊天对象集Message中,以供所有聊天用户访问。 接收用户的聊天信息是由多线程技术实现的,因为客户端必须时时关注更新服务器上是否有最新消息,在本程序中设定的是3秒刷新服务器一次,如果间隔时间太短将会增加客户端与服务器端的通信负担,而间隔时间长就会让人感觉没有时效性,所以经过权衡后认为3秒最佳,因为每个用户都不可能在3秒内连续发送信息。 当每次用户接收到聊天信息后将会开始分析聊天信息然后将适合自己的信息人性化地显示在聊天信息界面上。 4.1.1 问题陈述 1.接受用户注册信息并保存在一个基于文件的对象型数据库。 2.能够允许注册过的用户登陆聊天界面并可以聊天。 3.能够接受私聊信息并发送给特定的用户。 4.服务器运行在自定义的端口上#1001。 5.服务器监控用户列表和用户聊天信息(私聊除外)。 6.服务器踢人,发送通知。 7.服务器保存日志。

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧