TCP做的聊天项目(源代码)

[size=large][color=darkblue]package Utils;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JDialog;
import javax.swing.JFrame;
public class Utils {
public static void locateFrameCenter(JFrame frame) {
int frameWidth = frame.getWidth();// 对话框的宽度
int frameHeight = frame.getHeight();
Toolkit toolkit = Toolkit.getDefaultToolkit();// 获取默认工具包
Dimension screen = toolkit.getScreenSize();// 获取屏幕的大小
int screenwidth = screen.width;// 得到屏幕的宽度
int screenheight = screen.height;
// 设置对话框的位置
frame.setLocation((screenwidth - frameWidth) / 2,
(screenheight - frameHeight) / 2);
}
}


package Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import Utils.Utils;

/**
* 聊天室的服务器端
*
*/
public class Server extends JFrame{

private int count=0;//用来统计当前在线人数

private ArrayList<Socket> socketslist = new ArrayList<Socket>(); /** 用来保存所有客户端的socket列表 */

private ServerSocket server=null;

private Socket socket =null;

public Server() throws IOException{
this.init();
this.setTitle("聊天室服务端");
this.setSize(330, 230);
Utils.locateFrameCenter(this);
this.setResizable(false);//设置此窗体是否可由用户调整大小。
}

//启动监听
public void init() throws IOException{
ServerSocket server = new ServerSocket(9999);
System.out.println("服务器正在9999端口监听");
//监听并接收客户端
while(true){
socket = server.accept();
System.out.println("连接服务器成功");
socketslist.add(socket);
count++;
JOptionPane.showMessageDialog(this,"当前在线人数"+ count,"当前在线人数",
JOptionPane.INFORMATION_MESSAGE);

//针对每个客户端都启动一个线程单独跟它通信
Thread thread = new Thread(new ServerThread(socket, socketslist));
thread.start();
System.out.println("当前在线人数:"+count);
}
}

public static void main(String[] args) {
try {
new Server();
} catch (IOException e) {
e.printStackTrace();
}
}

}


package Server;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;

/**
*
* 服务器端跟客户端通信的线程类,把某个客户端发过来的数据转发给所有的客户端
*/
public class ServerThread implements Runnable {

private Socket currentsocket = null;//当前socket对象

private ArrayList<Socket> socketlist = null;//socket列表

public ServerThread(Socket currentsocket, ArrayList<Socket> socketlist) {
this.currentsocket = currentsocket;
this.socketlist = socketlist;
}

public void run() {
BufferedReader br =null;
PrintStream ps =null;
try {
//通过当前线程得到输入流
InputStream is = currentsocket.getInputStream();
//将字节输入流转化为字符输入流,在包装成字符缓冲流
br = new BufferedReader(new InputStreamReader(is));
String content;// 得到聊天内容
while ((content = br.readLine()) != null) {
// 将客户端接收到的内容发送给每一个客户,即往所有的客户端Socket写信息
for (int i = 0; i < socketlist.size(); i++) {
OutputStream os = socketlist.get(i).getOutputStream();
//得到每一个客户端socket对象,并得到对应的输出流
ps = new PrintStream(os);//用打印流进行包装,发送个每一个客户
ps.println(content);
ps.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(br!=null){
try{
br.close();
}catch(Exception e){
e.printStackTrace();
}

}
if(ps!=null){
try{
ps.close();
}catch(Exception e){
e.printStackTrace();
}

}
}

}
}


package Cilent;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import Utils.Utils;
/**
* 聊天室的客户端的图形界面
*/
public class Client extends JFrame {

private Socket socket; // 负责跟服务器通信的Socket

private JTextArea sendArea;// JTextArea 是一个显示纯文本的多行区域 /**发送文本框中的文本内容 */

private JTextArea contentArea; // 聊天文本框中的内容

private String name;// 当前用户的昵称

private JScrollPane sendPanel=null;// 发送内容的滚动面板

private JSplitPane splitPane=null;// 创建一个分隔窗格,JSplitPane 用于分隔两个(只能两个)Component

private JScrollPane contentPanel=null;// 聊天内容的滚动面板

private JPanel btnPanel=null; // 按钮面板

private JLabel nameLbl=null;//姓名标签

private JButton closeBtn=null;

private JButton clearBtn=null;

private JButton sendBtn=null;


public Client(Socket socket, String name) {
this.socket = socket;
this.name = name;
this.init();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);

// 启动一个单独的线程专门从服务器中读取数据
ClientThread thread = new ClientThread(socket, contentArea);
thread.start();
}

public void init() {
this.setTitle("龙虎房产工作组");
this.setSize(300, 400);
Utils.locateFrameCenter(this);
this.setResizable(false);// 设置此窗体是否可由用户调整大小

contentArea = new JTextArea();
contentArea.setLineWrap(true);
contentArea.setEditable(false);// 设置多行文本框不可编辑
// 设置文本区的换行策略。如果设置为 true,则当行的长度大于所分配的宽度时,将换行。如果设置为 false,则始终不换行。
contentPanel = new JScrollPane(contentArea);
// 聊天内容的滚动面板,JScrollPane(Component// view)
// 创建一个显示指定组件内容的 JScrollPane,只要组件的内容超过视图大小就会显示水平和垂直滚动条。

sendArea = new JTextArea();// 创建一个聊天记录区域文本框
sendArea.setLineWrap(true);
sendPanel = new JScrollPane(sendArea);// 发送内容的滚动面板

// 创建一个分隔窗格,JSplitPane 用于分隔两个(只能两个)Component
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
contentPanel, sendPanel);// 第一个参数是JSplitPane.HORIZONTAL_SPLIT(左右)
// 或 JSplitPane.VERTICAL_SPLIT(上下)
// 创建一个具有指定方向和不连续重绘的指定组件的新 JSplitPane
splitPane.setDividerLocation(270);// 设置分隔条的位置为 JSplitPane 大小的一个百分比。
this.add(splitPane, BorderLayout.CENTER);

btnPanel = new JPanel();
btnPanel.setLayout(new FlowLayout());// 按钮面板为流布局
this.add(btnPanel, BorderLayout.SOUTH);// 将按钮面板放在窗体的南面

nameLbl = new JLabel("昵称:" + this.name + " ");
btnPanel.add(nameLbl);
closeBtn = new JButton("关闭");
closeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);// 单击关闭按钮退出窗体
}
});
clearBtn = new JButton("清空");
clearBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
contentArea.setText("");// 清空聊天记录
}

});
btnPanel.add(clearBtn);
btnPanel.add(closeBtn);
sendBtn = new JButton("发送");

// 发送数据到服务器
sendBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 获取要发送的内容
String str = sendArea.getText();// 得到发送内容
SimpleDateFormat formater = new SimpleDateFormat("hh:mm:ss");
String time = formater.format(new Date());// 得到当前时间
String sendStr = name + " " + time + "\n" + str;// 聊天记录区域的内容

// 往服务器发
PrintWriter out = null;
try {
out = new PrintWriter(new OutputStreamWriter(socket
.getOutputStream()));
out.println(sendStr);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
sendArea.setText("");// 清空发送框的内容
}
});

btnPanel.add(sendBtn);
}
}


package Cilent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import Utils.Utils;
/**
* 聊天室的客户端登录界面
*
* @author qiujy
*
*/
public class ClientLogin extends JFrame {

private JTextField nameTxt;

private JPasswordField pwdFld;

private JPanel mainPanel = null; // 登录信息面板

private JLabel nameLbl = null;

private JLabel pwdLbl = null;

private JPanel btnPanel = null;

private JButton resetBtn = null;

private JButton loadBtn = null;

private JButton login = null;

public ClientLogin() {
this.init();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}

public void init() {
this.setTitle("QQ2010");
this.setSize(330, 230);
Utils.locateFrameCenter(this);
this.setResizable(false);// 设置此窗体是否可由用户调整大小。

mainPanel = new JPanel();
Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
// createEtchedBorder(int type)创建一个具有“浮雕化”外观效果的边框,将组件的当前背景色用于高亮显示和阴影显示。

// 参数: EtchedBorder.RAISED 或 EtchedBorder.LOWERED 之一

mainPanel.setBorder(BorderFactory.createTitledBorder(border, "输入登录信息"));
// 向现有边框添加一个标题,使其具有默认的位置(位于顶线上)、默认的调整 (leading),
// 以及默认的字体和文本颜色(由当前外观确定)。返回:TitledBorder 对象

this.add(mainPanel, BorderLayout.CENTER);// 设置登录面板的位置
mainPanel.setLayout(null);// 设置此容器的布局管理器。
mainPanel.setBackground(Color.gray);

nameLbl = new JLabel("昵称");// 创建具有指定文本的 JLabel(标签) 实例
nameLbl.setBounds(30, 30, 80, 22);// setBounds(int x, int y, int
// width, int height) 设置组件大小
mainPanel.add(nameLbl);// 将标签nameLbl添加到登录面板中
nameTxt = new JTextField();// 创建一个单行文本框
nameTxt.setBounds(115, 30, 120, 22);// 设置大小
mainPanel.add(nameTxt);// 将单行文本框(nameTx)添加到登录面板中

pwdLbl = new JLabel("密码");// 创建具有指定文本的 JLabel(标签) 实例
pwdLbl.setBounds(30, 60, 80, 22);
mainPanel.add(pwdLbl);// 将标签pwdLbl添加到登录面板中
pwdFld = new JPasswordField();
pwdFld.setBounds(115, 60, 120, 22);
mainPanel.add(pwdFld);// 将单行文本框(pwdFld)添加到登录面板中

btnPanel = new JPanel();// 按钮面板放置在JFrame的南边
// btnPanel.setLayout(new
// FlowLayout(FlowLayout.RIGHT));//设置(按钮)面板的布局为流布局,并设置对齐方式为右对齐
btnPanel.setLayout(new BorderLayout());// 设置按钮面板为边框布局
this.add(btnPanel, BorderLayout.SOUTH);
// 将btnPanel(按钮面板放)添加到Frame窗体中,布局方式为边框布局,并把它放到窗体的南边

login=new JButton("注册");//创建注册按钮
btnPanel.add(login,BorderLayout.CENTER);//将注册按钮的位置置于按钮面板的中央
login.addActionListener(new ActionListener(){//实现注册按钮的监听事件

public void actionPerformed(ActionEvent e) {
new UserRegester();//启动注册界面

}

});

resetBtn = new JButton("重置");// 创建按钮resetBtn
resetBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
nameTxt.setText("");
pwdFld.setText("");
}
});
btnPanel.add(resetBtn, BorderLayout.WEST);
btnPanel.setBackground(Color.gray);

loadBtn = new JButton("登录");// 创建按钮submitBtn
loadBtn.addActionListener(new LoginAction(this));
// 将LoginAction类的一个实例作为参数传进去,LoginAction类实现了ActionListener接口;
btnPanel.add(loadBtn, BorderLayout.EAST);// 将submitBtn加入到按钮面板中
}

// “登录”事件处理类
class LoginAction implements ActionListener {
private JFrame frame;

public LoginAction(JFrame frame) {
this.frame = frame;
}

public void actionPerformed(ActionEvent e) {
System.out.println("用户名" + nameTxt.getText() + ",密码是"
+ new String(pwdFld.getPassword()));

try {
// 连接到服务器....
Socket socket = new Socket("192.168.6.46", 9999);
// 当创建socket对象时会抛出 UnknownHostException(不合法的IP地址)和 IOException -
// 如果创建套接字时发生 I/O 错误。
// 连接上之后,显示聊天窗口
new Client(socket, nameTxt.getText());

// 本窗口销毁
frame.dispose();
} catch (UnknownHostException e1) {

JOptionPane.showMessageDialog(frame, "找不到指定的服务器!", "连接失败",
JOptionPane.ERROR_MESSAGE);
// 当发生异常时,弹出对话框显示错误信息
} catch (IOException e1) {
JOptionPane.showMessageDialog(frame, "连接服务器出错,请重试!", "连接失败",
JOptionPane.ERROR_MESSAGE);
}

}
}

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


package Cilent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

import javax.swing.JTextArea;

//客户端跟服务器通信的线程类
class ClientThread extends Thread{
private Socket socket = null; /** 客户端跟服务器连接上的Socket */
/** 聊天记录区域 */
private JTextArea contentArea = null;// JTextArea 是一个显示纯文本的多行区域

public ClientThread(Socket socket,JTextArea contentArea ){
this.socket=socket;
this.contentArea=contentArea;
}
public void run(){
BufferedReader br=null;
try{
InputStream is=socket.getInputStream();
br=new BufferedReader(new InputStreamReader(is)); //从输入流中读取数据添加到聊天记录区域中
String content;
while((content=br.readLine())!=null){
contentArea.append(content+"\n");
}

}catch(Exception e){
e.printStackTrace();
}
finally{
if(br!=null){
try{
br.close();
}catch(Exception e){
e.printStackTrace();
}
}

}

}
}


package Cilent;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JOptionPane;
public class UserRegester extends JFrame {

private JTextField nameTxt;

private JPasswordField pwdFld;

private JPasswordField setpwdFld;//确认密码

private JTextField emailFld;

private JPanel lesfPanel = new JPanel(new GridLayout(4,2));
private JPanel rightPanel = new JPanel();
private JPanel NorthPanel = new JPanel();
private JPanel CenterPanel = new JPanel();


private JLabel nameLbl = null;

private JLabel pwdLbl = null;

private JRadioButton menradio;
private JRadioButton womenradio;

private JLabel setpwdLbl = null;

private JLabel emailbl = null;

private JLabel sex = null;

private JLabel man = null;

private JLabel women = null;


private JButton tijiaoBtn = null;

public UserRegester() {
this.setTitle("用户注册界面");
this.setSize(200,140 );
this.setVisible(true);
this.setResizable(false);
init();
}

public void init() {
nameLbl=new JLabel("姓名");
nameTxt=new JTextField();
pwdLbl=new JLabel("密码");
pwdFld=new JPasswordField();
setpwdLbl=new JLabel("确认密码");
setpwdFld=new JPasswordField();
emailbl=new JLabel("邮箱");
emailFld=new JTextField();
lesfPanel.add(nameLbl);
lesfPanel.add(nameTxt);
lesfPanel.add(pwdLbl);
lesfPanel.add(pwdFld);
lesfPanel.add(setpwdLbl);
lesfPanel.add(setpwdFld);
lesfPanel.add(emailbl);
lesfPanel.add(emailFld);
this.add(lesfPanel,BorderLayout.NORTH);





sex=new JLabel("性别");
menradio=new JRadioButton();
man=new JLabel("男");
womenradio=new JRadioButton();
women=new JLabel("女");
rightPanel.add(sex);
rightPanel.add(menradio);
rightPanel.add(man);
rightPanel.add(womenradio);
rightPanel.add(women);
this.add(rightPanel,BorderLayout.CENTER);
this.add(CenterPanel,BorderLayout.SOUTH);

tijiaoBtn=new JButton("提交");
CenterPanel.add(tijiaoBtn);


tijiaoBtn.addActionListener(new tijiaoaction(this));

}

}
class tijiaoaction implements ActionListener{
JFrame frame;
public tijiaoaction(JFrame frame ){
this.frame=frame;
}
public void actionPerformed(ActionEvent e) {
int random=(int)(Math.random()*1000000);
JOptionPane.showMessageDialog(frame, ""+random, "您的QQ号码为", JOptionPane.CANCEL_OPTION);

}

}[/color][/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值