基于Android的简单聊天工具-服务器端
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的简单聊天工具-服务器端的更多相关文章
- 基于WebServices简易网络聊天工具的设计与实现
基于WebServices简易网络聊天工具的设计与实现 Copyright 朱向洋 Sunsea ALL Right Reserved 一.项目内容 本次课程实现一个类似QQ的网络聊天软件的功能:服务 ...
- [更新Github地址]python学习,自己写了个简单聊天工具mychat
最近在学习python,自己写了个最最简单的聊天工具mychatv0.1. 第一版,完成基本的聊天功能. GUI用的是自带的TKinter,用到的模块主要就是socket(网络编程), thread( ...
- C#基于Socket的简单聊天室实践
序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...
- Android 即时语音聊天工具 开发
使用融云SDK 1. 功能需求分析 1.1 核心功能需求: * 即时通讯 * 文字聊天 * 语音聊天 1.2 辅助功能需求: * 注册.登录 * 好友添加功能 * 好友关系管理 2. 融云即时通讯平台 ...
- c# UDP/TCP协议简单实现(简单聊天工具)
长时间没有摸这两个协议,写个代码温习下 下面是界面 [服务器界面] [登陆界面] [好友列表界面(我登陆了2个)] [聊天界面] 下面大致讲解下用到的内容 1.用户登陆于服务器通信用到的tcp协议,服 ...
- Netty 系列八(基于 WebSocket 的简单聊天室).
一.前言 之前写过一篇 Spring 集成 WebSocket 协议的文章 —— Spring消息之WebSocket ,所以对于 WebSocket 协议的介绍就不多说了,可以参考这篇文章.这里只做 ...
- 基于GUI的简单聊天室01
运用了Socket编程,gui,流的读入和写出,线程控制等 思路: 1.首先是在客户端中先建立好聊天的GUI 2.建立服务器端,设置好端口号(用SocketServer),其中需要两个boolean变 ...
- java自己写的简单聊天工具SimpleQQ感悟
Demo如下: 客户端: /* * 一个简单的QQ * 2013-8-1 * @李志杰 */ package SimpleQQ_Client; import java.awt.*; import ja ...
- 基于Android的串口聊天室 (基于tiny4412) 一
一.平台介绍 硬件平台: tiny4412ADK + S700 4GB Flash Android版本:Android-5.0.2 Linux版本: Linux-3.0.86 Bootloader:S ...
随机推荐
- Calendar简单用法
- [剑指Offer] 66.机器人的运动范围
题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能 ...
- mysql(二) 慢查询分析(一)
如下表结构: CREATE TABLE `trade_order` ( `order_id` ) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单编号', `t ...
- JAVA开发工作流程
阶段 0 :拟出一个计划 决定在后面的过程中采取哪些步骤,思考整个开发任务如何实现,分步骤建立“路标”,这样可以帮助自己开发时一步一个脚印的逐步完成,有效的防止自己在开发过程中迷失方向. 阶段 1 : ...
- set(gcf,'DoubleBuffer','on')
设置的目的是为了防止在不断循环画动画的时候会产生闪烁的现象,而这样便不会了.在动画的制作比较常用.
- Wannafly 挑战赛16 A 取石子
题目描述 给出四堆石子,石子数分别为a,b,c,d.规定每次只能从堆顶取走石子,问取走所有石子的方案数. 输入描述: 在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数 输 ...
- 【bzoj1705】[Usaco2007 Nov]Telephone Wire 架设电话线 dp
题目描述 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设在已有的N(2 <= N < ...
- bzoj 3275: Number (最小割)
题目的意思是要选一些数,但是这些数如果满足两个条件的话就不能一起被选. type arr=record toward,next,cap:longint; end; const maxn=; maxm= ...
- Eclipse的Project Facets属性设置解决项目无故报错
新检出项目,发现代码无故报错,各种尝试,最终发现是因为 项目右键中的 project Facets 属性中的 java 后面的 version 版本和项目 build path 的 jdk 版本不一 ...
- Hive架构及应用介绍【链接】
原文链接:https://blog.csdn.net/a2011480169/article/details/51482799