基于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 ...
随机推荐
- hibernate.cfg.xml的详细解释
<!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> < ...
- 载入其他同名源文件导致vs编译错误
今天下午工程编译的时候总是通不过,提示1,某个类没有某个成员,可是我去该类的头文件下查看,确实包括了这个成员啊.2,没有某个类,可是我明明定义了的. 检查了好久才发现 原来是,我打开了其他工程下的某一 ...
- [WC2005]双面棋盘
description 洛谷 给出一个\(n\times n\)的黑白棋盘. \(m\)次操作,每次将一个格子进行颜色翻转,求每次操作后的黑白四连通块数. data range \[n\le 200, ...
- 从零开始学Linux系统(一)之引导流程解析
Linux系统:分时多用户多任务的操作系统: Linux系统引导流程: inittab配置文件中: 定义了linux系统的运行的7个级别:从0~6 0.6:分别代表关机和重启,不建议设置为默认的运行级 ...
- 手动实现一个简易版SpringMvc
版权声明:本篇博客大部分代码引用于公众号:java团长,我只是在作者基础上稍微修改一些内容,内容仅供学习与参考 前言:目前mvc框架经过大浪淘沙,由最初的struts1到struts2,到目前的主流框 ...
- Linux内核中的常用宏container_of其实很简单
http://blog.csdn.net/npy_lp/article/details/7010752 通过一个结构体变量的地址,求该结构体的首地址. #ifndef CONTAINER_OF #de ...
- linux上修改系统默认语言设置
locale命令设置语言环境(临时修改) [keysystem@localhost ~]$ date Fri Feb :: CST [keysystem@localhost ~]$ locale LA ...
- STL使用总结
转载于http://blog.csdn.net/daisy_chenting/article/details/6898184 1. 概述 泛型编程思想最早缘于A.Stepanov提出的部分算法可 ...
- [Jenkins 新插件] 兼容阿里开发手册 (P3C) 的火线插件安装使用教程
一.前言 火线(Fireline)的Jenkins官方插件已经上线,目前火线不仅能检查出安卓代码中的安全类问题和内存泄露问题,还兼容了阿里开源的Java开发规约(P3C项目),本文将以教程的形式帮助大 ...
- Debug模式下加载文件,运行程序异常的慢
今天在进行单元测试的时候,debug模式下加载速度很慢,但是run模式下速度很快. 原因:在debug模式下,断点位置不当,解决办法 移除编译器中的所有断点.