在学校完成了简易的通讯软件制作
其中包含了
-
用户登录注册(链接数据库这里我是用了SQL SEVER)
-
简单的界面设计(没有使用插件WindowBuilder Pro,完全的代码实现)
-
简单的文字通讯(用了个appendView获取)
使用了 UDP 通讯,在发送接收消息上采用了“拉”的思想而
不是“推”,借以此解决了用户离线消息的问题。同时在服务器对于消息加上时间戳,避免了离线消息在拉取时消息跳跃顺序对于消息的同步顺序、重复过滤逻辑的影响。聊天系统在完成基础个人聊天之后,完成了多人聊天群聊的实现。在点对点单人聊天的基础上加入多个用户进入群聊中,捕获所有群聊中用户的地址与端口号。将发送方的消息打包多次发给各个用户的端口,实现群聊功能。
code
- [ 注册] 输入格式错误/成功提示,读入数据库操作
package main;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import bean.Qquser;
import service.QquserService;
import serviceimpl.QquserServiceimpl;
public class QQRec extends JFrame{
JTextField t1;
JPasswordField pwd1,pwd2;
QquserService qservice=new QquserServiceimpl();
public QQRec(){
super("QQ2015 - 注册");
Container c=getContentPane();
//设置窗口图标 1.07
//背景图片 1.12
//JLabel bgimg=new
//标题 1.16
JLabel title=new JLabel("新用户注册");
title.setFont(new Font("隶书",Font.BOLD,40));
title.setBounds(280, 10, 300,100);
c.add(title);
//昵称1.17
JLabel luname=new JLabel("昵称:");
luname.setFont(new Font("隶书",Font.BOLD,20));
luname.setBounds(150, 140, 80, 40);
c.add(luname);
t1=new JTextField();
t1.setBounds(250, 140 , 360, 40 );
t1.setFont(new Font("隶书",Font.BOLD,20));
c.add(t1);
//密码
JLabel lpwd1=new JLabel("密码:");
lpwd1.setFont(new Font("隶书",Font.BOLD,20));
lpwd1.setBounds(150, 240, 80, 40);
c.add(lpwd1);
pwd1=new JPasswordField();
pwd1.setBounds(250, 240 , 360, 40 );
pwd1.setFont(new Font("隶书",Font.BOLD,30));
c.add(pwd1);
//确认密码
JLabel lpwd2=new JLabel("确认密码:");
lpwd2.setFont(new Font("隶书",Font.BOLD,20));
lpwd2.setBounds(150, 340, 160, 40);
c.add(lpwd2);
pwd2=new JPasswordField();
pwd2.setBounds(250, 340 , 360, 40 );
pwd2.setFont(new Font("隶书",Font.BOLD,30));
c.add(pwd2);
//性别 1.28
//电话 1.29
//星座 1.31
//确认按钮
JButton b1=new JButton("提交");
b1.setFont(new Font("隶书",Font.BOLD,20));
b1.setBounds(110, 820, 140, 60);
c.add(b1);
b1.addActionListener(new MyActionListener());
//取消按钮
JButton b2=new JButton("取消");
b2.setFont(new Font("隶书",Font.BOLD,20));
b2.setBounds(510, 820, 140, 60);
c.add(b2);
b2.addActionListener(new MyActionListener());
//背景图片
JLabel bgimg=new JLabel(new ImageIcon("imgs/bg.png"));
c.add(bgimg);
setSize(800,1000);
setVisible(true);
setLocationRelativeTo(null);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("提交")) {
String nickname=t1.getText().trim();
String p1=pwd1.getText().trim();
String p2=pwd2.getText().trim();
if(nickname.equals("")) {
JOptionPane.showMessageDialog(null, "请输入昵称!");
t1.requestFocus();
}else if(p1.equals("")) {
JOptionPane.showMessageDialog(null, "请输入密码!");
pwd1.requestFocus();
}else if(p2.equals("")) {
JOptionPane.showMessageDialog(null, "请确认密码!");
pwd2.requestFocus();
}else if(!p1.equals(p2)) {
JOptionPane.showMessageDialog(null, "两次密码输入不一致!");
pwd2.requestFocus();
}else {
//提交数据 1.51
Qquser quser=new Qquser();
quser.setQqnum(Qnum());
quser.setUname(nickname);
quser.setIpadd("127.0.0.1");//IP
quser.setPort(getPort());//方法生成端口
quser.setPwd(p2);
//注册
boolean bln=qservice.addUSer(quser);
if(bln) {
JOptionPane.showMessageDialog(null, "恭喜注册成功,您的QQ号是"+quser.getQqnum());
}else {
JOptionPane.showMessageDialog(null, "注册失败!");
}
}
}else if(e.getActionCommand().equals("取消")) {
QQRec.this.dispose();//关闭注册窗口
}
}
}
//qq号码生成
public String Qnum() {
Random r=new Random();
int i=r.nextInt(10000);
while(i<1000) {
i=r.nextInt(10000);
}
//判断qq号是否已经存在 1.58
return i+"";
}
//端口生成
public int getPort() {
Random r=new Random();
int i=r.nextInt(10000)+10000;
//5位数
return i;
}
public static void main(String[] args) {
new QQRec();
}
}
端口号一定要设置位数多一点以防备用。
- [ 登录] 在数据库内检查数据正确并且给予反馈
package main;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import bean.Qquser;
import main.QQRec.MyActionListener;
import service.QquserService;
import serviceimpl.QquserServiceimpl;
public class QQLogin extends JFrame{
//账号和密码框 0.22
JLabel l1,l2,loginbtn;
JButton b1;
JComboBox t1;
JPasswordField pwd1;
JCheckBox c1,c2;
String[] accs= {""};
QquserService qservice=new QquserServiceimpl();
public QQLogin() {
super("QQ2019登录");
//查询登录历史1.28
//设置样式 0.33
Container c=getContentPane();
//头像
// JLabel face=new JLabel(new ImageIcon("imgs/touxiang1.png"));
// face.setBounds(30, 190, 60, 60);
// c.add(face);
Color mycolor=new Color(15,117,255);
//账号
JLabel s1,s2;
s1=new JLabel("账号:");
s1.setBounds(140, 150, 80, 40);
s1.setFont(new Font("",Font.PLAIN,20));
s1.setForeground(mycolor);
c.add(s1);
//QQ账号输入框
t1=new JComboBox(accs);
t1.setEditable(true);//设置可以编辑
t1.setBounds(200,150,190,40);
t1.setFont(new Font("",Font.PLAIN,30));
c.add(t1);
//注册账号 0.25
l1=new JLabel("注册账号");
l1.setBounds(400, 150, 80, 40);
l1.setFont(new Font("",Font.PLAIN,20));
l1.setForeground(mycolor);
c.add(l1);
l1.setCursor(new Cursor(Cursor.HAND_CURSOR));
l1.addMouseListener(new MyMouseListener());
//密码
s2=new JLabel("密码:");
s2.setBounds(140, 200, 80, 40);
s2.setFont(new Font("",Font.PLAIN,20));
s2.setForeground(mycolor);
c.add(s2);
//密码框 0.29
pwd1=new JPasswordField();
pwd1.setBounds(200,200,190,40);
pwd1.setFont(new Font("",Font.PLAIN,30));
c.add(pwd1);
//忘记密码 0.29
l2=new JLabel("忘记密码");
l2.setBounds(400, 200, 80, 40);
l2.setFont(new Font("",Font.PLAIN,20));
c.add(l2);
l2.setForeground(mycolor);
l2.setCursor(new Cursor(Cursor.HAND_CURSOR));
//记住密码自动登录复选框0.30
Color myco=new Color(90,90,90);
c1=new JCheckBox("记住密码");
c1.setBounds(175,250,120,20);
c1.setFont(new Font("",Font.PLAIN,20));
c.add(c1);
c1.setForeground(myco);
c1.setCursor(new Cursor(Cursor.HAND_CURSOR));
c2=new JCheckBox("自动登录");
c2.setBounds(300,250,120,20);
c2.setFont(new Font("",Font.PLAIN,20));
c.add(c2);
c2.setForeground(myco);
c2.setCursor(new Cursor(Cursor.HAND_CURSOR));
//登录按钮0.31 new ImageIcon("imgs/login1.png")
// loginbtn=new JLabel("登录");
// loginbtn.setFont(new Font("隶书",Font.BOLD,20));
// loginbtn.setBounds(420,320,232,40);
// c.add(loginbtn);
// loginbtn.addMouseListener(new MyMouseListener());
JButton b1=new JButton("登录");
b1.setFont(new Font("隶书",Font.BOLD,20));
b1.setBounds(200,300,180,40);
c.add(b1);
b1.addActionListener(new MyActionListener());
//背景图片0.6
JLabel bgimg=new JLabel(new ImageIcon("imgs/bg.png"));
c.add(bgimg);
setSize(650,500);
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//鼠标事件的监听 0.35
class MyMouseListener extends MouseAdapter{
public void mouseClicked(MouseEvent e) {
if(e.getSource()==l1) {//如果是注册账号
new QQRec();
}
}
}
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("登录")) {
//获取账号
String qqNum=t1.getSelectedItem().toString().trim();
//获取密码
String pwd=pwd1.getText().trim();
if(qqNum.equals("")) {
JOptionPane.showConfirmDialog(null, "请输入账号!");
t1.requestFocus();
return;
}else if(pwd.equals("")) {
JOptionPane.showConfirmDialog(null, "请输入密码!");
pwd1.requestFocus();
return;
}
//0.53
Qquser quser=new Qquser();
quser.setQqnum(qqNum);
quser.setPwd(pwd);
//验证登录 0.48 0.51:49
Qquser qu=qservice.chkUser(quser);
if(qu==null) {
JOptionPane.showConfirmDialog(null, "账号密码有误!");
pwd1.requestFocus();
return;
}else {
//修改在线状态1.03
//qservice.updUserState(quser);
//将登录信息保存到数据库表中 1.05:19
//保存登录历史 1.10
//关闭登录窗口
QQLogin.this.dispose();
//打开QQ主面板
new QQMain(quser);
}
//数据库建立0.57
}
}
}
public static void main(String[] args) {
new QQLogin();
}
}
- [ 登陆后主界面] 显示自己,显示好友,显示群聊
package main;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTabbedPane;
import bean.QQMsg;
import bean.Qquser;
import common.Contents;
import main.QQMain.MyDefaultListCellRenderer;
import main.QQMain.MyListModel;
import service.QquserService;
import serviceimpl.QquserServiceimpl;
import main.QQchat;
public class QQMain extends JFrame{
JList flist;
Vector<Qquser> fvecot;
QquserService qservice = new QquserServiceimpl();
Qquser quser,frienduser;
Map<String,QQchat> chats;
public QQMain(Qquser qu) {
super("QQ2019");
this.quser=qu;
Container c=getContentPane();
//显示昵称
JLabel nick=new JLabel ("你的昵称:");
nick.setFont(new Font("微软雅黑",Font.PLAIN,30));
nick.setBounds(0,0,150,50);
c.add(nick);
JLabel nickname=new JLabel (quser.getUname());
nickname.setFont(new Font("微软雅黑",Font.PLAIN,30));
Color mycolor=new Color(15,117,255);
nickname.setForeground(mycolor);
nickname.setBounds(130,0,100,50);
c.add(nickname);
//显示qq账号
JLabel num=new JLabel ("你的账号:");
num.setFont(new Font("微软雅黑",Font.PLAIN,30));
num.setBounds(0,50,150,50);
c.add(num);
JLabel numname=new JLabel (quser.getQqnum());
numname.setFont(new Font("微软雅黑",Font.PLAIN,30));
numname.setForeground(mycolor);
numname.setBounds(130,50,100,50);
c.add(numname);
//
flist=new JList();
flist.setFixedCellHeight(80);
flist.addMouseListener(new MyMouseListener());
//动态设置内容
this.flushMain();
// //好友切换面板 0.47
JTabbedPane tab=new JTabbedPane();
tab.add("好友",flist);
//
c.add(tab);
tab.setBounds(0,100,500,800);
//背景图片
JLabel bgimg=new JLabel(new ImageIcon("imgs/bg.png"));
c.add(bgimg);
setSize(500,800);
setVisible(true);
setLocation(2000,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//启动接收线程
new MyThread().start();
}
class MyListModel extends AbstractListModel{
Vector<Qquser> vv=new Vector<Qquser>();
public MyListModel(Vector<Qquser> users) {
this.vv=users;
}
public Object getElementAt(int index) {
return null;
}
public int getSize() {
return vv.size();
}
}
//动态更改Jlist中的选项
class MyDefaultListCellRenderer extends DefaultListCellRenderer{
Vector<Qquser> datas=new Vector<Qquser>();
public MyDefaultListCellRenderer(Vector<Qquser> users) {
this.datas=users;
}
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
//Jlist 有数据才进去
if(index>=0&&index<=datas.size()) {
Qquser quser=datas.get(index);
//String icon=quser.getFace();//图片路径
//设置头像
//如果是隐身或者离线
// if(quser.getState()==Contents.STATE_HIDE||quser.getState()==Contents.STATE_DOWNLINE) {
// //从
// icon=icon.substring(0, icon.indexOf("."));
// icon=icon+"_h.png";//imgs/touxiang0_h.png
// //在线
// }else if(quser.getState()==Contents.STATE_ONLINE) {
//
//
// //请勿打扰
// }else if(quser.getState()==Contents.STATE_BUSY) {
// icon=icon.substring(0, icon.indexOf("."));
// icon=icon+"_w.png";//imgs/touxiang0_w.png
// //离开
// }else if(quser.getState()==Contents.STATE_LEAVE) {
// icon=icon.substring(0, icon.indexOf("."));
// icon=icon+"_l.png";//imgs/touxiang0_l.png
// }
//给JList设置图标头像
setIcon(new ImageIcon("imgs/7.png"));
//给JList设置QQ号和签名
setText(quser.getUname()+"["+quser.getQqnum()+"]");
setFont(new Font("微软雅黑",Font.PLAIN,30));
}
//设置鼠标经过的样式
if (isSelected) {// 如果被选中了
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setEnabled(list.isEnabled());
setFont(list.getFont());
return this;
}
}
//刷新面板
public void flushMain() {
//从数据库中根据用户QQ号和分组名称 查询出4个vector
fvecot=qservice.selFriendByGroup(quser.getQqnum());
//动态给JList设置内容
flist.setModel(new MyListModel(fvecot));
flist.setCellRenderer(new MyDefaultListCellRenderer(fvecot));
flist.setFont(new Font("",Font.PLAIN,50));
}
//鼠标事件的监听
class MyMouseListener extends MouseAdapter{
public void mouseClicked (MouseEvent e) {
if(e.getSource()==flist) {
if(flist.getSelectedIndex()>=0){ //获取JList是否有选中某一项
frienduser=fvecot.get(flist.getSelectedIndex());
//双击了鼠标左键
if(e.getButton()==1&e.getClickCount()==2){
// System.out.println("双击了鼠标左键");
// new QQchat(quser,frienduser);
openChat(frienduser.getQqnum(),null);
}
if(e.getButton()==3){
//点击了鼠标右键
}
}
}
//System.out.println(frienduser.getQqnum());
}
}
//打开聊天窗口(好友的号码 消息类)
public QQchat openChat(String qqmun,QQMsg msg) {
//去集合中查找是否有该好友的聊天面板
QQchat chat=chats.get(qqmun);
if(chat==null) {
if(msg!=null) {//线程打开的窗口
Qquser myuser=msg.getMyuser();//我
Qquser fruser=msg.getFruser();//好友
chat=new QQchat(fruser,myuser);//初始化面板
}else{//双击打开的窗口
chat=new QQchat(quser,frienduser);//初始化面板
}
//把对象放到集合中
chats.put(qqmun, chat);
}
if(!chat.isVisible()) {//如果窗口隐藏
chat.t1.setText("");
chat.setVisible(true);
}
return chat;
}
public void openChat(Qquser frienduser2) {
// TODO 自动生成的方法存根
}
//接收线程
class MyThread extends Thread{
public MyThread() {
//初始化集合
chats=new HashMap<String,QQchat>();
}
@Override
public void run() {
//自己的端口
int port=quser.getPort();
try {
//搭载接受服务器 接受自己端口的消息
DatagramSocket ds=new DatagramSocket(port);
while(true){//循环接收
byte[] b=new byte[1024*50];//每次接收50k
DatagramPacket dp=new DatagramPacket(b,b.length);
ds.receive(dp);
ByteArrayInputStream bis=new ByteArrayInputStream(b,0,dp.getLength());
//转换成对象输入流
ObjectInputStream ois=new ObjectInputStream(bis);
//得到了消息对象
QQMsg msg=(QQMsg) ois.readObject();
int cmd=msg.getCmd();//消息字
if(cmd==Contents.CMD_INLINE) {
}else if(cmd==Contents.CMD_OFFLINE) {
}else if(cmd==Contents.CMD_CHAT) {//聊天
//好友的QQ 消息内容
QQchat chat= openChat(msg.getMyuser().getQqnum(), msg);
//将消息内容显示在面板中
chat.appendView(msg.getMyuser().getUname(), msg.getDoc());
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
/* public static void main(String[] args) {
Qquser quser=new Qquser();
quser.setUname("zsy");
quser.setQqnum("1000");
new QQMain(quser);
}*/
}
- [ 聊天框界面] (纯手打界面框,没有用到组件)需要有接收消息的数据包,以及发送消息的数据包监听
package main;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import bean.QQMsg;
import bean.Qquser;
import common.Contents;
import common.SendMsg;
public class QQchat extends JFrame {
JButton send, cancel;
Qquser me, friend;
JTextPane t1, t2;
public QQchat(Qquser me, Qquser friend) {
super("与" + friend.getUname() + "聊天中");
this.me = me;
this.friend = friend;
Container c = getContentPane();
// 显示昵称
JLabel nickname = new JLabel(friend.getUname());
nickname.setBounds(5, 5, 100, 30);
c.add(nickname);
nickname.setFont(new Font("微软雅黑", Font.BOLD, 30));
// 对话框
t1 = new JTextPane();
JScrollPane pan1 = new JScrollPane(t1);
pan1.setBounds(25, 50, 720, 360);
c.add(pan1);
t1.setEditable(false);
t1.setFont(new Font("微软雅黑", Font.BOLD, 30));
// 发送框
t2 = new JTextPane();
JScrollPane pan2 = new JScrollPane(t2);
pan2.setBounds(25, 500, 720, 360);
c.add(pan2);
t2.setFont(new Font("微软雅黑", Font.BOLD, 30));
// 取消
cancel = new JButton("取消");
c.add(cancel);
cancel.setBounds(200, 870, 120, 40);
cancel.addActionListener(new MyActionListener());
// 发送
send = new JButton("发送");
c.add(send);
send.setBounds(600, 870, 120, 40);
send.addActionListener(new MyActionListener());
// 背景图片
JLabel bgimg = new JLabel(new ImageIcon("imgs/bg.png"));
c.add(bgimg);
setSize(800, 1000);
setVisible(true);
setLocationRelativeTo(null);
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == send) {
try {
// 把输入框的内容显示到接受框
appendView(me.getUname(), t2.getStyledDocument());
// 将消息发送给好友
QQMsg msg = new QQMsg();
msg.setCmd(Contents.CMD_CHAT);// 消息状态字
msg.setMyuser(me);
msg.setFruser(friend);
msg.setDoc(t2.getStyledDocument());// 聊天消息内容
new SendMsg().send(msg);// 发送
} catch (BadLocationException e1) {
e1.printStackTrace();
}
t2.setText("");
} else if (e.getSource() == cancel) {
// 将自己隐藏
QQchat.this.setVisible(false);
}
}
}
// 获取接受框内容
public void appendView(String name, StyledDocument xx) throws BadLocationException {
StyledDocument vdoc = t1.getStyledDocument();// 输入的文本
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String time = sdf.format(date);
SimpleAttributeSet as = new SimpleAttributeSet();
String s = name + " " + time + "\n";
vdoc.insertString(vdoc.getLength(), s, as);
int end = 0;
while (end < xx.getLength())
{
Element e0 = xx.getCharacterElement(end);
SimpleAttributeSet asl = new SimpleAttributeSet();
StyleConstants.setForeground(asl, StyleConstants.getForeground(e0.getAttributes()));
StyleConstants.setFontSize(asl, StyleConstants.getFontSize(e0.getAttributes()));
StyleConstants.setFontFamily(asl, StyleConstants.getFontFamily(e0.getAttributes()));
s = e0.getDocument().getText(end, e0.getEndOffset() - end);
if ("icon".equals(e0.getName()))
{
vdoc.insertString(vdoc.getLength(), s, e0.getAttributes());
}
else
{
vdoc.insertString(vdoc.getLength(), s, asl);
}
end = e0.getEndOffset();
}
vdoc.insertString(vdoc.getLength(), "\n", as);
t1.setCaretPosition(vdoc.getLength());
}
}
- [ 连接数据库] (哭辽,这个连了老半天,一点技术含量都没)
package common;
import java.sql.*;
public class DBConnection {
private static String url="jdbc:sqlserver://127.0.0.1:1433;databasename=QQ";//路径
private static String driver="com.microsoft.sqlserver.jdbc.SQLServerDriver";//驱动
private static String username="sa";
private static String pwd="123456";
private static Connection conn=null;
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
if(conn==null||conn.isClosed()){
conn=DriverManager.getConnection(url,username,pwd);
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return conn;
}
public static void main(String[] args) {
System.out.println(getConnection());
}
}
- [ 转化消息为字节流]
package common;
import bean.QQMsg;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
public class SendMsg {
//发送消息
public void send(QQMsg msg) {
//获取字节输出流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
//转化成对象输出流
try {
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(msg);
//将字节流转化成字节数组
byte[] b=bos.toByteArray();
DatagramSocket ds = new DatagramSocket();
//发送 是 获取好友的IP和端口
InetAddress add=InetAddress.getByName(msg.getFruser().getIpadd());
int port =msg.getFruser().getPort();
DatagramPacket dp = new DatagramPacket(b, 0, b.length, add, port);
//发送
ds.send(dp);
ds.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
- [ 聊天内部系统命令字]
package common;
public class Contents {
//命令字
public static final int CMD_INLINE=1000;//上线通知
public static final int CMD_OFFLINE=1001;//下线通知
public static final int CMD_BUSY=1002;//忙碌通知
public static final int CMD_LEAVE=1003;//离开通知
public static final int CMD_CHAT=1004;//聊天通知
public static final int CMD_SHKAE=1005;//抖动通知
public static final int CMD_ADDFRIEND=1006;//添加好友通知
public static final int CMD_DELFRIEND=1007;//删除好友通知
public static final int CMD_SENDFILE=1008;//发送文件通知
}
- [ 传输返回用户数据] (对于 UDP 通信而言主要流程如下:
UDP 发送端:
建立 updsocket 服务。
提供数据,并将数据封装到数据包中。
通过 socket 服务的发送功能,将数据包发出去。
关闭资源。
UDP 接收端:
定义 udpsocket 服务,通常会监听一个端口。
定义一个数据包,存储接收到的字节数据。
通过 socket 服务的 receive 方法将收到的数据存入已定义好的数据包中。
通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上)//终于到我写的部分了
package bean;
import java.io.Serializable;
public class Qquser implements Serializable{
private int id;//--id
private String qqnum ;//--QQ号
private String uname;//--昵称
private String pwd ;//--密码
private String ipadd ;//--IP
private int port ;//--端口
private int state;
public String getIpadd() {
return ipadd;
}
public void setIpadd(String ipadd) {
this.ipadd = ipadd;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQqnum() {
return qqnum;
}
public void setQqnum(String qqnum) {
this.qqnum = qqnum;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
- [ 传输返回消息]
package bean;
import java.io.Serializable;
import javax.swing.text.StyledDocument;
//QQ消息类
public class QQMsg implements Serializable{//流化
private int cmd;//命令
private Qquser myuser;//自己的用户信息
private Qquser fruser;//好友的用户信息
private StyledDocument doc;//消息对象
private String fileName;//文件
public int getCmd() {
return cmd;
}
public void setCmd(int cmd) {
this.cmd = cmd;
}
public Qquser getMyuser() {
return myuser;
}
public void setMyuser(Qquser myuser) {
this.myuser = myuser;
}
public Qquser getFruser() {
return fruser;
}
public void setFruser(Qquser fruser) {
this.fruser = fruser;
}
public StyledDocument getDoc() {
return doc;
}
public void setDoc(StyledDocument doc) {
this.doc = doc;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
- [ 传输历史消息]
package bean;
//0.59
public class QqHistory {
private int id;
private String qqnum;
private String pwd;
private String face;
private int autologin;//
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQqnum() {
return qqnum;
}
public void setQqnum(String qqnum) {
this.qqnum = qqnum;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public int getAutologin() {
return autologin;
}
public void setAutologin(int autologin) {
this.autologin = autologin;
}
}
第一次用着种能自动填充的ide,好舒服_,觉得JAVA就是无数个api累积使用的语言,当然目前我作为学生还没有考虑到大量用户并发,没有考虑到java函数方法使用的技巧,这个作为一个作业,也是自己第一个写完的具有一丢丢规模完整的java程序,能完成还是很高兴的。