时间比较紧,技术能力有限,现在代码中肯定存在很多问题
把做的思路及代码发上来
一是理清自己的思路
二是大家有什么好的建议
三是等待牛人给好的思路修正一些问题
为了存储注册用户信息,好友之间的关系,需要建立两张表
qq注册用户的信息表
qq_friend表 这个表是关联qqinfo的id,两个字段都是外键
表建立好了,那么根据一般方式
写个数据库操作的工具类吧
public class ConnectionUtil {
private final static String url="jdbc:mysql://localhost:3306/qq?useUnicode=true&characterEncoding=UTF-8";
private final static String username="root";
private final static String password="root";
private static Connection instance=null;
private ConnectionUtil(){
if(instance==null){
try {
Class.forName("org.gjt.mm.mysql.Driver");
instance=DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static Connection getConnection(){
if(instance==null){
new ConnectionUtil();
}
return instance;
}
public static void close(Connection con,PreparedStatement ps,ResultSet rs){
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
con=null;
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps=null;
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs=null;
}
}
}
public static void close(Connection con,PreparedStatement ps){
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
con=null;
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps=null;
}
}
}
public static void close(Connection con){
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
con=null;
}
}
}
}
工具类写完后,实体相应写出,省略getter setter方法
QQinfo表的实体
public class QQInfo {
private Integer id;
private String name;
private String password;
private String status;
}
public class QQFriend {
private Integer myId;
private List<Integer> friendId;
}
下来就是DAO了
public class QQFriendDAO {
/**
* 添加好友
*/
public static void addFriend(int myId,int friendId ){
Connection con=ConnectionUtil.getConnection();
PreparedStatement ps=null;
String sql="insert into id_friendid(myId,friendId) value(?,?)";
try {
ps=con.prepareStatement(sql);
ps.setInt(1, myId);
ps.setInt(2, friendId);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps);
}
}
/**
* 移除好友
*/
public static void removeFriend(int myId,int friendId){
Connection con=ConnectionUtil.getConnection();
PreparedStatement ps=null;
String sql="delete from id_friendid where myId=? and friendId=? ";
try {
ps=con.prepareStatement(sql);
ps.setInt(1, myId);
ps.setInt(2, friendId);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps);
}
}
/**
* 查找好友
*/
public static List<Integer> getFriends(int myId){
List<Integer> list=new ArrayList<Integer>();
Connection con=ConnectionUtil.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
String sql="select friendId from id_friendid where myId=? ";
try {
ps=con.prepareStatement(sql);
ps.setInt(1, myId);
rs=ps.executeQuery();
while(rs.next()){
list.add(rs.getInt("friendId"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps);
}
return list;
}
}
public class QQInfoDAO {
/**
* 根据id查找相应的qq信息
*
*/
public QQInfo getQQInfo(int id){
QQInfo qqInfo=null;
Connection con=ConnectionUtil.getConnection();
String sql="select * from qqinfo where id=?";
PreparedStatement ps=null;
ResultSet rs=null;
try {
ps=con.prepareStatement(sql);
ps.setInt(1, id);
rs=ps.executeQuery();
if(rs.next()){
qqInfo=new QQInfo();
qqInfo.setId(id);
qqInfo.setName(rs.getString("name"));
qqInfo.setPassword(rs.getString("password"));
qqInfo.setStatus(rs.getString("status"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps,rs);
}
return qqInfo;
}
/**
* 更新个人信息
*/
public void update(QQInfo qqInfo){
Connection con=ConnectionUtil.getConnection();
PreparedStatement ps=null;
String sql="update qqinfo set name=?,password=?,status=? where id=?";
try {
ps=con.prepareStatement(sql);
ps.setString(1, qqInfo.getName());
ps.setString(2, qqInfo.getPassword());
ps.setString(3, qqInfo.getStatus());
ps.setInt(4, qqInfo.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps);
}
}
/**
* 注册新号码
*/
public void save(QQInfo qqInfo){
Connection con=ConnectionUtil.getConnection();
PreparedStatement ps=null;
String sql="insert into qqinfo(name,password,status) value(?,?,?)";
try {
ps=con.prepareStatement(sql);
ps.setString(1, qqInfo.getName());
ps.setString(2, qqInfo.getPassword());
ps.setString(3, qqInfo.getStatus());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUtil.close(con,ps);
}
}
}
然后写Test测试DAO是否有问题,这里就省略了,测试都通过
前面的结束后,复杂的东西就开始了,一般我有点晕就开始按流程来理思路
那么用户现在已经通过web注册了一个QQ号(写个jsp页面,通过上面的DAO,写个servlet,让用户注册)
他开始登陆自己的QQ
那么这个登陆的时候填写的信息,发送到服务器,然后给他验证
这个发送信息,服务器接受信息处理,再加上socket接受
服务器处理完信息后就关闭吗?肯定要连着,如果这会再有其它QQ连上来,就需要多线程
发送到服务器的信息有很多种类型,有的是用户登陆信息,有的是发送消息信息, 有的是线好友的信息
这个信息跑过来,跑过去的,需要给定义个类
public interface MessageType {
String message_succeed="1";//表明是登陆成功
String message_login_fail="2";//表明登录失败
String message_comm_mes="3";//普通信息包
String message_get_onLineFriend="4";//要求在线好友的包
String message_ret_onLineFriend="5";//返回在线好友的包
}
public class Message implements java.io.Serializable{
private static final long serialVersionUID = 1L;
/**
* 信息是哪种类型
*/
private String mesType;
/**
* 发送者名字
*/
private String sender;
/**
* 接受者名字
*/
private String getter;
/**
* 信息内容
*/
private String con;
/**
* 信息发送时间
*/
private String sendTime;
}
项目为了清晰,分为两个ServerQQ ,ClientQQ,以上的两个类两个项目里面都会用到
下面就是处理连接了,连接上来读取到客户端的发来的信息,然后处理完成后再发送过去,又让我想到了web的MVC
只不过这个发送的方式不是通过jsp页面发送表现的,需要自己画界面,从节目里面获取值,然后进行封装
web是写好jsp,只等着在web容器里面处理前台做好标记的数据,而且还有struts之类的东东,实在是爽翻了。这CS开发都要自己写,还要处理多线程,客户端没有浏览器,要自己写个软件,相当于浏览器,后台也要自己来接受,没有web容器前期就给你很多处理。
public class QqClientConServer {
public Socket s;
//发送第一次请求
public boolean sendLoginInfoToServer(Object o)
{
boolean b=false;
try {
s=new Socket("127.0.0.1",9999);
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
oos.writeObject(o);
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Message ms=(Message)ois.readObject();
//判断服务器发送过来的消息
if(ms.getMesType().equals("1"))
{
//就创建一个该qq号和服务器端保持通讯连接得线程
ClientConServerThread ccst=new ClientConServerThread(s);
//启动该通讯线程
ccst.start();
ManageClientConServerThread.addClientConServerThread
(((QQInfo)o).getId(), ccst);
b=true;
}else{
s.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
}
return b;
}
}
里面涉及到一个ManageClientConServerThread
public class ManageClientConServerThread {
private static HashMap hm=new HashMap<String, ClientConServerThread>();
//把创建好的ClientConServerThread放入到hm
public static void addClientConServerThread(int qqId,ClientConServerThread ccst)
{
hm.put(qqId, ccst);
}
//可以通过qqId取得该线程
public static ClientConServerThread getClientConServerThread(String qqId)
{
return (ClientConServerThread)hm.get(qqId);
}
}
当你连接上了服务器,然后你跟服务器保持通讯,那么还能一机登录多个QQ吗?
这个manager就是为了实现这个
以前看java的时候,在想为什么客户端socket不需要制定端口号
百科->>
引用
如何开发一个Server-Client模型的程序
开发原理:
服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
客户端已经好了,就等服务器了
服务端要面对N个客户端连接上来,压力啊
一个server等待连接客户端得连接,N个客户端线程连接请求上来后你怎么处理
先考虑一个连接上来吧,上来后要这个实例要面对N中请求处理,多线程来执行里面的处理可能会更好,毕竟不能让socket闲着,这个IO还是很昂贵的
为了面对N个客户端的连接,采用manger,跟客户端一样
public class MyQqServer {
public MyQqServer() {
try {
// 在9999监听
System.out.println("服务器在9999监听");
ServerSocket ss = new ServerSocket(9999);
// 阻塞,等待连接
while (true) {
Socket s = ss.accept();
// 接收客户端发来的信息.
ObjectInputStream ois = new ObjectInputStream(s
.getInputStream());
QQInfo qqInfoClient = (QQInfo) ois.readObject();
Message m = new Message();
ObjectOutputStream oos = new ObjectOutputStream(s
.getOutputStream());
QQInfoDAO qqInfoDAO = new QQInfoDAO();
QQInfo qqInfoServer = qqInfoDAO.getQQInfo(qqInfoClient.getId());
if (qqInfoClient.getPassword().equals(qqInfoServer.getPassword())) {
// 返回一个成功登陆的信息报
m.setMesType("1");
oos.writeObject(m);
// 这里就单开一个线程,让该线程与该客户端保持通讯.
SerConClientThread scct = new SerConClientThread(s);
ManageClientThread.addClientThread(qqInfoServer.getName(), scct);
// 启动与该客户端通信的线程.
scct.start();
// 并通知其它在线用户.
scct.notifyOther(qqInfoServer.getId());
} else {
m.setMesType("2");
oos.writeObject(m);
// 关闭Socket
s.close();
}
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
} finally {
}
}
}
public class SerConClientThread extends Thread{
Socket s;
public SerConClientThread(Socket s)
{
//把服务器和该客户端的连接赋给s
this.s=s;
}
//让该线程去通知其它用户
public void notifyOther(int iam)
{
//得到所有在线的人的线程
HashMap hm=ManageClientThread.hm;
Iterator it=hm.keySet().iterator();
while(it.hasNext())
{
Message m=new Message();
m.setCon(""+iam);
m.setMesType(MessageType.message_ret_onLineFriend);
//取出在线人的id
String onLineUserId=it.next().toString();
try {
ObjectOutputStream oos=new ObjectOutputStream(ManageClientThread.getClientThread(onLineUserId).s.getOutputStream());
m.setGetter(onLineUserId);
oos.writeObject(m);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}
public void run()
{
while(true)
{
//这里该线程就可以接收客户端的信息.
try {
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Message m=(Message)ois.readObject();
//对从客户端取得的消息进行类型判断,然后做相应的处理
if(m.getMesType().equals(MessageType.message_comm_mes))
{
//一会完成转发.
//取得接收人的通信线程
SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter());
ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());
oos.writeObject(m);
}else if(m.getMesType().equals(MessageType.message_get_onLineFriend))
{
System.out.println(m.getSender()+" 要他的好友");
//把在服务器的好友给该客户端返回.
String res=ManageClientThread.getAllOnLineUserid();
Message m2=new Message();
m2.setMesType(MessageType.message_ret_onLineFriend);
m2.setCon(res);
m2.setGetter(m.getSender());
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
oos.writeObject(m2);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class ManageClientThread {
public static HashMap hm=new HashMap<String, SerConClientThread>();
//向hm中添加一个客户端通讯线程
public static void addClientThread(String uid,SerConClientThread ct)
{
hm.put(uid, ct);
}
public static SerConClientThread getClientThread(String uid)
{
return (SerConClientThread)hm.get(uid);
}
//返回当前在线的人的情况
public static String getAllOnLineUserid()
{
//使用迭代器完成
Iterator it=hm.keySet().iterator();
String res="";
while(it.hasNext())
{
res+=it.next().toString()+" ";
}
return res;
}
}
---------------截止到现在,基本解决了登录问题,登录后管理连接问题,那登录后要好友显示什么的
根据号码搜索好友,加好友--->>这个功能暂时不实现
客户A--发送查询信息
服务器--接受到消息类型,查询相关信息出来,发送到客户端,客户端A看到信息决定是否加
如果加--发送次信息到服务器
服务器--悲剧,又要判断加的好友在不在线,不在线还得把这个存起来,然后,他上线再通知。
先放着吧,以后再实现
------------------------------------
view层代码有些问题,明天再发出来吧。
希望大家给给些意见
- 大小: 22.2 KB
- 大小: 17.9 KB
- 大小: 26.2 KB
分享到:
相关推荐
【IAPP源码】聊天软件IAPP源码+php后端【IAPP源码】聊天软件IAPP源码+php后端【IAPP源码】聊天软件IAPP源码+php后端【IAPP源码】聊天软件IAPP源码+php后端【IAPP源码】聊天软件IAPP源码+php后端【IAPP源码】聊天软件...
基于HTML+CSS+PHP+JS+MySQL的web端即时聊天软件源码+使用说明+sql数据库.tar基于HTML+CSS+PHP+JS+MySQL的web端即时聊天软件源码+使用说明+sql数据库.tar基于HTML+CSS+PHP+JS+MySQL的web端即时聊天软件源码+使用说明+...
程序设计思维小作业基于python和flask的简易版网页聊天软件源码+数据库(高分项目)程序设计思维小作业基于python和flask的简易版网页聊天软件源码+数据库(高分项目)程序设计思维小作业基于python和flask的简易版...
基于 C# WinForm sockets的在线聊天软件源码+论文(毕业设计).zip 已获导师指导并认可的高分毕业设计项目,代码完整确保可以运行。 基于 C# WinForm sockets的在线聊天软件源码+论文(毕业设计).zip 已获导师...
基于Windows系统+qt框架的语音聊天网站源码+项目说明.zip基于Windows系统+qt框架的语音聊天网站源码+项目说明.zip基于Windows系统+qt框架的语音聊天网站源码+项目说明.zip基于Windows系统+qt框架的语音聊天网站源码+...
操作系统课程设计、网络聊天室源码+项目说明(高分课程设计).zip操作系统课程设计、网络聊天室源码+项目说明(高分课程设计).zip操作系统课程设计、网络聊天室源码+项目说明(高分课程设计).zip操作系统课程设计...
基于AI+区块链加密技术的去中文化的私有聊天机器人源码+部署说明.zip基于AI+区块链加密技术的去中文化的私有聊天机器人源码+部署说明.zip基于AI+区块链加密技术的去中文化的私有聊天机器人源码+部署说明.zip基于AI+...
基于QT+C++开发的高仿QQ聊天软件+源码+项目说明,适合期末大作业、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于QT+C++开发的高仿QQ聊天软件+源码+项目说明,适合期末大...
Java大作业基于SSM与websocket开发的实时在线聊天室源码+sql数据库+运行截图.zipJava大作业基于SSM与websocket开发的实时在线聊天室源码+sql数据库+运行截图.zipJava大作业基于SSM与websocket开发的实时在线聊天室...
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和...基于SSM+JDK1.8+tomcat7+maven3.6.0的 Web版在线聊天室源码+项目说明.zip
标题和描述中提到的“高仿9158视频语音聊天网源码+服务端+客户端+网站程序”是指一个模仿9158(一个早期流行的在线视频语音聊天平台)的全套软件开发资源。这套资源包含了实现类似功能所需的全部代码,包括服务端...
基于java的聊天系统设计(源码+文档)基于java的聊天系统设计(源码+文档)基于java的聊天系统设计(源码+文档)基于java的聊天系统设计(源码+文档)基于java的聊天系统设计(源码+文档)基于java的聊天系统设计...
基于JSP+Ajax+MyEclipse 2015 Java聊天室软件源码+说明文档 通过本课程设计的实践及其前后的准备与总结,复习、领会、巩固和运用软件工程课堂上所学的软件开发方法和知识,以此来完成Java聊天室的分析、设计、编码、...
采用SpringBoot+Vue框架开发的网页版聊天室项目源码+数据库+使用说明采用SpringBoot+Vue框架开发的网页版聊天室项目源码+数据库+使用说明采用SpringBoot+Vue框架开发的网页版聊天室项目源码+数据库+使用说明采用...
基于muduo网络库Reactor模型的集群聊天源码+项目说明.zip基于muduo网络库Reactor模型的集群聊天源码+项目说明.zip基于muduo网络库Reactor模型的集群聊天源码+项目说明.zip基于muduo网络库Reactor模型的集群聊天源码+...
"网狐6.6完整源码+内核源码+105款游戏源码(已解密)"是一个非常珍贵的资源,对于深入理解网络游戏的开发流程、架构设计以及优化技术有着重要的参考价值。下面,我们将围绕这个主题展开深入探讨。 首先,"网狐6.6...
nodejs + socket.io 的多人在线聊天后台系统+源码+运行教程,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ nodejs + socket.io 的多人在线聊天后台系统+源码+...
程序设计思维小作业基于python flask写一个简易版网页聊天软件源码+数据库,实现登录、注册、文字聊天功能 运行方式 python main.py 主要思路 登录和注册使用数据库,用POST方法传输数据,登录后用session存储登录的...
基于sqlite数据库以及深度学习lstm实现的检索式聊天机器人python源码+数据集+模型+代码注释.zip基于sqlite数据库以及深度学习lstm实现的检索式聊天机器人python源码+数据集+模型+代码注释.zip基于sqlite数据库以及...
毕业设计 基于java+DES加密的即时通信聊天系统源码+部署文档+全部数据资料(优秀项目).zip毕业设计 基于java+DES加密的即时通信聊天系统源码+部署文档+全部数据资料(优秀项目).zip毕业设计 基于java+DES加密的...