基于socket的即时通讯的研究毕业设计 下载本文

4 系统实现

4.1 客户端的实现

在前面我们已经详细的介绍了服务器的实现,但是对于一个C/S模式的项目来说,我们还必须对客户端进行设计和实现,下面的就是对客户端的设计。

在本项目里面客户端和服务器端是通过socket建立连接通道进行数据交换的。服务器与客户都通过构造ObjectOutputStream、ObjectInputStream来建立输入流和输出流,双方通过该输入流和输出流来相互传递信息。只要收到客户端的连接请求,服务器利用accept()函数返回一个新建的Socket对象,随后客户端向服务器发送消息,比如注册、登录和查找同事等请求,服务器收到请求后,针对不同的消息处理请求。

本系统是基于socket的局域网即时通讯,本系统的客户端是用android语言编写的移动客服端,使用了mvc设计模型技术[5]。即显示与控制的代码是分开写的,这样减少了各个模块的耦合性,提高了这个项目的可维护性。

4.1.1 登录模块的实现

首先我们先来整理下登录模块的运行的机制,正如我们所知的,在通讯领域里面登录模块是一个很重要的模块。在客户端里面输入你的用户账号与密码登录,那么此时服务器接收到账号和密码后和数据库里面的用户表匹配,判断是否登录成功。

登陆的的时候先判断socket是否连接了。只有前台与后台连接了才把当前用户提交给后台,判断用户表里面是否存在了这个用户,后台数据库的sql语句的实现为:String sql

= \

前台提交数据代码的实现:

/**

* 提交账号密码信息到服务器 */

private void login() {

String accounts = mAccounts.getText().toString(); String password = mPassword.getText().toString(); if (accounts.length() == 0 || password.length() == 0) {

DialogFactory.ToastDialog(this, \登录\亲!帐号或密码不能为空哦\showRequestDialog(); // 通过Socket验证信息 if (application.isClientStart()) {

Client client = application.getClient();

ClientOutputThread out = client.getClientOutputThread();

TranObject o = new TranObject(TranObjectType.LOGIN); User u = new User();

13

} else {

}

}

}

u.setId(Integer.parseInt(accounts));

u.setPassword(Encode.getEncode(\o.setObject(u); out.setMsg(o);

if (mDialog.isShowing())

mDialog.dismiss();

\亲!服务器暂未开放哦\

DialogFactory.ToastDialog(LoginActivity.this, \登录\

} else {

4.1.2 注册模块的具体实现

注册的时候先判断socket连接是否来存在,不存在的话重新再连接一次。如果连接后台的话,就把当前用户注册的用户名和密码记录到后台。后台如果注册成功的话就生成一个用户的id,并且生产一个用户的id的好友列表,用户使用这个id登陆。

前台代码的实现:

private void regist() { //

String email = mEmailEt.getText().toString(); String name = mNameEt.getText().toString(); String passwd = mPasswdEt.getText().toString(); String passwd2 = mPasswdEt2.getText().toString(); if (email.equals(\

|| passwd2.equals(\

\亲!带*项是不能为空的哦\

DialogFactory.ToastDialog(RegisterActivity.this, \注册\

} else {

if (passwd.equals(passwd2)) {

showRequestDialog(); // 提交注册信息

if (application.isClientStart()) {// 如果已连接上服务器

Client client = application.getClient(); Client client = GetMsgService.client;

ClientOutputThread out = client.getClientOutputThread(); TranObject o = new TranObject(

TranObjectType.REGISTER);

User u = new User(); u.setEmail(email);

14

} /**

* 注册成功后,创建一个用户表,保存该用户好友 *

* @param id */

public void createFriendtable(int id) {

Connection con = DButil.connect(); try {

String sql = \

+ \+ \+ \+ \+ \+ \

}

} else { }

DialogFactory.ToastDialog(RegisterActivity.this, \注册\

\亲!您两次输入的密码不同哦\

\

}

u.setName(name);

//u.setPassword(Encode.getEncode(%u.setPassword(passwd);//不加密 o.setObject(u); out.setMsg(o);

if (mDialog.isShowing())

mDialog.dismiss();

DialogFactory.ToastDialog(this, \注册\\亲!服务器暂未开放哦

} else {

后台代码的实现

PreparedStatement ps = con.prepareStatement(sql); int res = ps.executeUpdate(); System.out.println(res);

} catch (SQLException e) {

15

}

}

e.printStackTrace(); DButil.close(con);

} finally {

4.1.3 聊天信息界面的实现

在本项目聊天信息的里面信息的接收和发送都是通过socket连接来实现的。使用Socket对局域网上本地的服务器的一个端口发出连接请求,如果连接成功,打开本次会话;会话完成后,关闭这次创建的Socket连接。总的来说就是,当服务端开启socket服务,客服端每次连接服务器成功的话服务器端会创建一个线程来处理这个连接,这个连接是存放在线程池里面统一管理的。如过这个连接结束的话就是释放这个线程。

(1)信息发送

(2)每次用户发送消息的时候,先把要发送的消息封装到消息类里面,再把要发送的消息封装到TranObject类里面,这个类负责向后台发送封装的数据。有发送的数据,来自哪个用

户,发给哪个用户的信息,再通过ClientOutputThread 类向服务器发送信息。每次发送完数据

清空输入框。关键代码的实现如下:

private void send() {

String contString = mEditTextContent.getText().toString(); if (contString.length() > 0) {

ChatMsgEntity entity = new ChatMsgEntity(); entity.setName(util.getName()); entity.setDate(MyDate.getDateEN()); entity.setMessage(contString); entity.setImg(util.getImg()); entity.setMsgType(false);

messageDB.saveMsg(user.getId(), entity); mDataArrays.add(entity);

mAdapter.notifyDataSetChanged();// 通知ListView,数据已发生改变 mEditTextContent.setText(\清空编辑框数据

mListView.setSelection(mListView.getCount() - 1);// 发送一条消息时,ListView显MyApplication application = (MyApplication) this

.getApplicationContext();

Client client = application.getClient();

ClientOutputThread out = client.getClientOutputThread();

16

示选择最后一项