1、数据库用的mysql,一共有3张表,一张用户表user、一张朋友列表friend和一张消息表message。

1 User table      用户表
uid 主键自动生成
userName 昵称
userPwd 密码
userSex 性别
userPho 用户头像,有默认头像
2 Friend table 好友列表
fid 主键自动生成
uid --> fk 用户id,外键
fuid --> 朋友的id
fName 好友名称
3 Messages table 消息表
mid 消息id,主键自动生成
fromid --> fk from id 发送者id
tofid --> fk to id 接收者id
msg 消息内容
mtime 发送时间

2、服务器端架构

3、model包解析

public class User{//1 用户类
private String userName;//用户名
private String userPwd;//用户密码
private String userSex;//用户性别
private String userPho;//用户照片
...
public class Friend {//2 朋友类
private int uid;//用户id
private int fuid;//friend id
private String fName;//用户的朋友名字
...
public class FriendList extends ArrayList<Friend>{//3 朋友列表类
/**
*
*/
private static final long serialVersionUID = 1L;
private FriendList friendlist;
public FriendList() {
friendlist = null;
}
}
public class Messages{//4 消息类
private int fromId;
private int toId;
private String msg;
private String mtime;
public Messages() { }

4、db包解析

主要作用是加载类,获取mysql数据库的连接

public class DBConnection {
public static final String DBURL = "jdbc:mysql://localhost:3306/qq";
public static final String DBUSER = "root";
public static final String DBPASS = "root";
public static final String DBDRIVER = "com.mysql.jdbc.Driver"; static {
try {
Class.forName(DBDRIVER);//加载类
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//返回Connection
public Connection getConnect() throws SQLException{
return DriverManager.getConnection(DBURL,DBUSER,DBPASS);
}
//关闭资源
public void close(Connection con, Statement sta, ResultSet rs) {
try {
rs.close();
if(con != null) {
con.close();
}
if(sta != null) {
sta.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

5、util包解析

第一个类Packager

public class Packager {
//用于登录数据包的分析
public String loginPackager(String operate,String friends,String result) {
StringBuffer mes = new StringBuffer("");
mes.append("operate:" + operate + "\n");
mes.append("content:" + friends);
mes.append("result:" + result + "\n");
return mes.toString();
}
//用于发送数据包的分析
public String sendPackager(String operate,String msg,String result) {
StringBuffer mes = new StringBuffer("");
mes.append("operate:" + operate + "\n");
mes.append("content:" + "\n");
mes.append("result:" + result + "\n");
return mes.toString();
}
}

第二个类Parser

public class Parser {
//解析类
//用于解析获取的请求类型是什么,比如登录、发送消息
public String getOperate(String request) {
String[] message = request.split("\n");
String operate = message[0].substring(8,message[0].length());
return operate;
}
//获取内容
public String getContent(String request) {
String[] message = request.split("\n");
String content = message[1].substring(8,message[1].length());
return content;
}
//获取发送的消息
public Messages parseMessages(String content) {
String[] mes = content.split("#");
int toId = Integer.parseInt(mes[0]);
String message = mes[1];
Messages msg = new Messages();
msg.setToId(toId);
msg.setMsg(message);
return msg;
}
//将字符串解析为用户类,返回用户类
public User parseUser(String content) {
//分隔符为#
String[] mes = content.split("#");
//第一个是用户名,第二个是密码
String userName = mes[0];
String userPwd = mes[1];
User user = new User();
user.setUserName(userName);
user.setUserPwd(userPwd);
return user;
}
}

  

6、controll包解析

controller类解析

//控制器
public class Controller {
//无参构造函数
public Controller() { }
//相应请求
public String doResponse(String request,String ip) {
Parser parser = new Parser();
String operate = parser.getOperate(request);//用于解析用户的请求操作是什么
String content = parser.getContent(request);//获取请求的内容
String response = null;//相应字符串
String friends = null;//朋友
if("login".equals(operate)) {//判断是否是登录请求
int uid = login(content);//返回该用户的id,如果没有该用户返回0
String result = null;
if(uid != 0) {
//将该用户的主键和ip地址加入管理客户端类中
ManageClients.addIps(new Integer(uid), ip);
result = "success";//如果登陆成功,那么获得该用户的所有朋友列表
friends = getFriends(uid);
}else{
result = "fail";//登录失败
}
Packager packager = new Packager();
response = packager.loginPackager(operate,friends,result);
}else if("sendMessage".equals(operate)) {//如果是发送消息
Messages msg = parser.parseMessages(content);
int toId = msg.getToId();//找到要接受者的id
String ipaddress = ManageClients.ips.get(new Integer(toId)).toString();//通过id 获得ip地址
ServerThread sendto = (ServerThread)ManageClients.clients.get(ipaddress);//通过ip地址获取接受者的线程
sendto.send(msg.getMsg());//向发送端发送信息
Packager packager = new Packager();
String result = "success";
response = packager.sendPackager(operate,null,result);
}
return response;
}
public String getFriends(int uid) {
String sql = "select fid,uid,fuid,fName from friend where uid=" + uid;
DBConnection dbc = new DBConnection();
Connection con = null;
Statement sta = null;
ResultSet rs = null;
StringBuilder sb = new StringBuilder("");
try {
con = dbc.getConnect();
con = dbc.getConnect();
sta = con.createStatement();
rs = sta.executeQuery(sql);
while(rs.next()) {
sb.append(rs.getInt(1)+"#" + rs.getInt(2) + "#" + rs.getInt(3) + "#" + rs.getString(4) + "\n");
}
} catch (SQLException e) {
e.printStackTrace();
}
return sb.toString();
}
public int login(String content) {//登录操作,登陆成功,返回朋友列表,否则返回错误原因
Parser parser = new Parser();
User user = parser.parseUser(content);//获取用户类
//然后去数据库中查询是否有该用户,如果有该用户,那么返回该用户的主键id
String sql = "select uid,userPwd from user where userName='" + user.getUserName() +"'";
DBConnection dbc = new DBConnection();
Connection con = null;
Statement sta = null;
ResultSet rs = null;
String dbpwd = null;
int uid = 0;
try {
con = dbc.getConnect();
sta = con.createStatement();
rs = sta.executeQuery(sql);
while(rs.next()) {
uid = rs.getInt(1);
dbpwd = rs.getString(2);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
dbc.close(con, sta, rs);
}
if(dbpwd != null && dbpwd.equals(user.getUserPwd()) && uid != 0) {
return uid;
}else{
uid = 0;
return uid;
}
}

7、server包解析

7.1 Server类 开启监听端口,不断监听请求的用户

public class Server {
public static void main(String[] args) {
new Server();
}
public Server()
{
ServerSocket serversocket = null;
Socket socket = null;
try {
serversocket = new ServerSocket(5000);
System.out.println("服务器已经启动,正在监听5000端口");
while(true) {
socket = serversocket.accept();
String ip = socket.getLocalAddress().getHostAddress();
ServerThread st = new ServerThread(socket,ip);//服务器端线程
st.start();
ManageClients.addClients(ip, st);//将该线程添加到ManageClients类中
int port = socket.getPort();
System.out.println("连接上的客户端ip:" + ip + ",端口号:" + port);
}
} catch (IOException e) {
e.printStackTrace();
} }
}

7.2 ServerThread类 ,用于转发消息

public class ServerThread extends Thread{
private Socket socket;
private String ip;
private InputStream in;
private OutputStream out;
private static final int SIZE = 1024;
public Socket getSocket(){
return socket;
}
public ServerThread(Socket socket,String ip) {
this.socket = socket;
this.ip = ip;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String mes) {
try {
out.write(mes.getBytes());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void close() {
try {
if(in != null){
in.close();
in = null;
}
if(out != null) {
out.close();
out = null;
}
if(socket != null) {
socket.close();
socket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true) {
try {
byte[] buffer = new byte[SIZE];
int index = in.read(buffer);
String message = new String(buffer,0,index);//获取客户端发送过来的请求
Parser parser = new Parser();
String operate = parser.getOperate(message);
Controller controller = new Controller();
if(operate.equals("exit")) {
break;
} String response = controller.doResponse(message,ip);//服务器处理发送过来的消息,如果不是收获
//的操作不是exit
if(response != null)
send(response);//向客户端发送请求操作的结果
} catch (IOException e) {
e.printStackTrace();
}finally{
close();
}
} }

7.3 ManageClients

public class ManageClients {
//管理客户端 ,用HashMap存储用户ip和线程的键值对
public static HashMap<String,ServerThread> clients = new HashMap<String,ServerThread>();//string sender
//用于用户主键 和ip之间的键值对
public static HashMap<Integer,String> ips = new HashMap<Integer,String>();
public static void addClients(String senderip, ServerThread st) {
clients.put(senderip, st);
}
public static void addIps(Integer i, String ip) {
ips.put(i, ip);
}
}

服务器端结束 ,启动Server中的main 函数,监听是否有客户端请求

基于Android的简单聊天工具-服务器端的更多相关文章

  1. 基于WebServices简易网络聊天工具的设计与实现

    基于WebServices简易网络聊天工具的设计与实现 Copyright 朱向洋 Sunsea ALL Right Reserved 一.项目内容 本次课程实现一个类似QQ的网络聊天软件的功能:服务 ...

  2. [更新Github地址]python学习,自己写了个简单聊天工具mychat

    最近在学习python,自己写了个最最简单的聊天工具mychatv0.1. 第一版,完成基本的聊天功能. GUI用的是自带的TKinter,用到的模块主要就是socket(网络编程), thread( ...

  3. C#基于Socket的简单聊天室实践

    序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...

  4. Android 即时语音聊天工具 开发

    使用融云SDK 1. 功能需求分析 1.1 核心功能需求: * 即时通讯 * 文字聊天 * 语音聊天 1.2 辅助功能需求: * 注册.登录 * 好友添加功能 * 好友关系管理 2. 融云即时通讯平台 ...

  5. c# UDP/TCP协议简单实现(简单聊天工具)

    长时间没有摸这两个协议,写个代码温习下 下面是界面 [服务器界面] [登陆界面] [好友列表界面(我登陆了2个)] [聊天界面] 下面大致讲解下用到的内容 1.用户登陆于服务器通信用到的tcp协议,服 ...

  6. Netty 系列八(基于 WebSocket 的简单聊天室).

    一.前言 之前写过一篇 Spring 集成 WebSocket 协议的文章 —— Spring消息之WebSocket ,所以对于 WebSocket 协议的介绍就不多说了,可以参考这篇文章.这里只做 ...

  7. 基于GUI的简单聊天室01

    运用了Socket编程,gui,流的读入和写出,线程控制等 思路: 1.首先是在客户端中先建立好聊天的GUI 2.建立服务器端,设置好端口号(用SocketServer),其中需要两个boolean变 ...

  8. java自己写的简单聊天工具SimpleQQ感悟

    Demo如下: 客户端: /* * 一个简单的QQ * 2013-8-1 * @李志杰 */ package SimpleQQ_Client; import java.awt.*; import ja ...

  9. 基于Android的串口聊天室 (基于tiny4412) 一

    一.平台介绍 硬件平台: tiny4412ADK + S700 4GB Flash Android版本:Android-5.0.2 Linux版本: Linux-3.0.86 Bootloader:S ...

随机推荐

  1. Ninject学习资料

    https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel http://www.cnblogs.com/willick/p/3223 ...

  2. bzoj1069-最大土地面积

    题目 给定\(n\ (n\le 2000)\)个坐标,求四个坐标使得围起来的四边形面积最大. 分析 最暴力的想法是枚举四个点,然而肯定超时.接着不知道怎么想到中途相遇,然而一点关系都没有.这里用到了一 ...

  3. BZOJ 1415 聪聪和可可(期望DP)

    我们可以用n次BFS预处理出 to[][]数组,to[i][j]表示聪聪从i点到j点第一步会走哪个点. 那么对于聪聪在i点,可可在j点,聪聪先走,定义dp[i][j]表示步数期望. 那么显然有dp[i ...

  4. BZOJ4864 BeiJing 2017 Wc神秘物质(splay)

    splay维护区间最大值.最小值.相邻两数差的绝对值的最小值即可. #include<iostream> #include<cstdio> #include<cmath& ...

  5. hdu 1150 Machine Schedule (二分匹配)

    Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. [洛谷P1552][APIO2012]派遣

    题目大意:有一棵$n$个点的树,和一个费用$m$,每个点有一个费用和价值,请选一个点,再从它的子树中选取若干个点,使得那个点的价值乘上选的点的个数最大,要求选的点费用总和小于等于$m$ 题解:树形$d ...

  7. BZOJ3140:[HNOI2013]消毒——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3140 https://www.luogu.org/problemnew/show/P3231 最近在 ...

  8. SpringAOP简介

    AOP(Aspect Orient Programming) --- 面向切面编程 将分散在各个业务逻辑中的相同代码 通过 “横向”切割方式抽取到独立模块中 方式抽取到独立模块中;[它针对的是程序运行 ...

  9. ES6 Set,WeakSet,Map,WeakMap

    1. Set Set是一个集合,里面的值都是唯一的,没有重复的.Set中可以是任何数据类型,并且添加数据时会进行严格比较,重复数据无法加入. 2. WeakSet 弱引用Set.只能存储对象,不能存储 ...

  10. [技巧篇]16.MyEclipse2014安装SVN插件,在线安装

    这两天想做点东西,但是现在流行的是git,但是军哥的项目是托管到阿里的svn代码当中,所以没有办法,还需要弄SVN,这里不将什么安装SVN等东西 我要求的就是快速入门而已,仅此而已,我安装成功,过程很 ...