android聊天室设计Word下载.docx
- 文档编号:7960598
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:21
- 大小:278.36KB
android聊天室设计Word下载.docx
《android聊天室设计Word下载.docx》由会员分享,可在线阅读,更多相关《android聊天室设计Word下载.docx(21页珍藏版)》请在冰点文库上搜索。
3.2服务器功能实现4
3.2.1StartServer类4
3.2.2ServerThread类5
3.2.3ClientThread类6
3.2.4BroadCast类8
3.2.1DoDataBase类10
3.3客户端功能实现11
3.4系统功能展示15
3.4.1客户端功能展示15
3.4.2服务器端及数据库展示16
4系统存在的问题及改进方法17
4.1系统存在的问题17
4.2系统改进方法17
4自我评价18
参考文献19
1TCP/IP及Socket简介
1.1TCP/IP协议简介
TCP/IP是TransmControlProtocol/InternetProtocol的简写,又称网络通信协议,是Internet最基本的协议。
TCP/IP协议是“可靠的”、“面相连接”的网络传输协议。
TCP/IP协议遵循的是一个抽象的分层模型,这个模型中所有的TCP/IP系列网络协议都被归纳到四个抽象的“层”中。
每一抽象层建立在低一层提供的服务上,并为高一层服务。
TCP/IP参考模型从上到下分别包括网络接口层、网络互连层、传输层和应用层四层。
1.2Socket套接字简介
在网络上的两个程序通过一个双向的通信链路实现数据交换,这个双向链路的一段就被称为一个Socket,Socket通常用来实现客户端和服务器端的链接。
Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket有一个IP地址和一个端口号确定。
在Java环境中实现基于TCP/IP协议的网络编程都需要采用Socket机制。
并且与基于URL的网络编程Socket编程提供更高的传输效率。
Socket通常采用C/S结构,使用Socket进行C/S程序设计的一般链接过程如下图:
图1.1Socket编程连接一般过程
2系统总体架构
整个系统由客户端和服务器端组成,其中客户端位于Android模拟器上,服务器端位于PC上。
客户端创建的Socket与服务端的ServerSocket进行交互来实现网络数据交互。
其中Socket与ServerSocket交互过程如下:
(1)服务器端程序创建一个ServerSocket,然后调用accept()方法等待客户连接
(2)客户端创建一个Socket并请求与服务器端程序建立连接。
(3)服务器端程序接受客户端的连接请求,并创建一个新的Socket与该客户端建立专线连接。
(4)建立了连接的客户端及服务器端的两个Socket在一个有服务器端程序创建的单独线程上对话,对话方式采用getInputStream()、getOutputStream()得到的输入与输出流进行数据的读取与输出。
客户端的Socket与服务器端的ServerSocket的通信如下图:
图2.1Socket与ServerSocket通信图
(5)服务器端开始等待新的连接请求,重复
(2)~(5)的过程。
在客户端程序实现了界面的显示以及与服务器端的数据交互。
在服务器端程序一共包含五个类,其名称及功能如下表所示:
StartServer
启动服务器主线程ServerThread,即启动服务器
ServerThread
服务器监听端口线程,负责创建ServerSocket以及监听是否有新客户端连接,并记录客户端连接以及需要发送的消息
ClientThread
维持服务器与单个客户端的连接线程,负责接受客户端发送来的消息
BroadCast
服务器向客户端发送广播线程,负责向客户端发送消息
DoDataBase
连接数据库,将消息拆解后按类型存放到数据库ChatDemo的messages表中
表2.1服务器端程序的四个类功能
实现通信功能的流程图如下:
图2.2系统通信功能流程图
3系统功能实现
3.1数据交互格式
对于此聊天系统,主要存在如下三类数据:
1、登陆
2、传递消息
3、退出
这三类数据都是需要向服务器端发送的数据,因为了在服务器端处理的数据不被混淆,必须对他们的数据格式进行规格化,此系统的数据规格如下图:
表3.1消息格式图
消息种类:
“L”—登陆;
“S”——传递消息;
“C”——退出,
目的地址:
要发往特定客户端的手机号
标识:
用来标识不同种类的信息符号其中“$$”——发送的消息标识;
“##”——客户上下线标识。
源地址:
消息来源的客户端手机号码
时间:
获取到的发送消息时的时间
内容:
如果登陆则为“上线了”,如果退出则为“下线了”,如果是传递消息则为想发送的内容;
其中对于登陆和退出消息,送往服务器端进行拆分后将其目标地址置空,对于传递消息,如果目标地址和源地址相同则表示将该消息发送给所有的客户端,反之,则只是发送到这两个地址的客户端中。
3.2服务器端功能实现
3.2.1StartServer类
StartServer线程是整个服务器的主线程,当执行这个工程文件时执行这个类中的Main函数,在Main函数中创建了一个实例化了一个ServerThread线程命名为serverThread,并启动该线程,代码如下:
publicclassStartServer{
privatestaticServerThreadserverThread;
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
serverThread=newServerThread();
serverThread.start();
}
}
3.2.2ServerThread类
该类在构造函数中实例化了两个Vector数组,分别用于存放ClientThread线程和存放从客户端发送来的消息,并命名为clients和messages。
此外还对ServerSocket进行了初始化,然后启动BroadCast方法。
代码如下:
publicVector<
ClientThread>
clients;
Object>
messages;
publicServerThread(){
clients=newVector<
();
messages=newVector<
try{
serverSocket=newServerSocket(PORT);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
myIpaddress=InetAddress.getLocalHost();
}catch(UnknownHostExceptione){
broadcast=newBroadCast(this);
broadcast.start();
构造方法执行后,接着执行该线程的Run()方法。
在Run()函数中用了一个死循环实现不停的对客户端的连接进行监听,一旦监听到客户端的连接请求,就获得该客户端的Socket并将其封装在ClientThread线程中,然后启动ClientThread线程并将该线程压入clients数组中以实现服务器与指定客户端或所有客服端发送数据。
此外由于clients属于临界资源,同一时刻只能允许被一个线程操作,因此使用了线程同步方法synchronized(clients)。
publicvoidrun(){
while(true){
try{
Socketsocket=serverSocket.accept();
System.out.println(socket.getInetAddress().getHostAddress());
ClientThreadclientThread=newClientThread(socket,this);
clientThread.start();
if(socket!
=null){
synchronized(clients){
clients.addElement(clientThread);
}
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
3.2.3ClientThread类
当ServerThread线程开启了ClientThread线程后,通过构造函数获得了客户端的Socket套接字,然后通过Socket的getInputStream()方法和getOutputStream()方法获取输入输出流。
publicClientThread(Socketsocket,ServerThreadserverThread){
this.clientSocket=socket;
this.serverThread=serverThread;
in=newDataInputStream(clientSocket.getInputStream());
out=newDataOutputStream(clientSocket.getOutputStream());
然后执行Run()方法监听Socket是否有新的消息,然后根据消息的类别相应处理后在控制台上显示出来,并把message的第14到25的子串(username)作为ClientThread的唯一标识ID,此标识可以用来实现从一个客户端向另一指定客户端发送数据。
并利用doMsg()方法将message拆分后存放到数据库中,同时将message压入到messages消息队列中。
publicvoidrun(){
Stringmessage=in.readUTF();
synchronized(serverThread.messages)
{
if(message!
=null)
{
doMsg(message);
ID=message.substring(14,25);
serverThread.messages.addElement(message);
if(message.subSequence(0,1).equals("
S"
))
{
if(message.substring(1,12).equals(message.substring(14,25)))
{
System.out.println(message.substring(1,12)+message.substring(24));
}
else{
System.out.println("
$$"
+message.substring(14,25)+"
对"
+message.substring(1,12)+message.substring(25));
}
else
System.out.println(message.substring(12));
break;
privatevoiddoMsg(Stringmessage){
catgory=message.substring(0,1);
orgid=message.substring(14,25);
time=message.substring(26,34);
if(catgory.equals("
)){
goalid=message.substring(1,12);
content=message.substring(36);
else
{
goalid="
"
;
content=message.substring(34);
dodb.AddMsg(time,catgory,orgid,goalid,content);
}catch(Exceptione){
3.2.4BroadCast类
通过ServerThread线程调用该类后,ServerThread类通过BroadCast构造函数传给ServerThread实例,然后执行该线程的Run()方法,没循环一次线程休眠200ms,然后取出messages中尚未发送出的消息,将消息按其格式拆分后根据其意图送往各个客户端或是指定客户端,是实现群聊个私聊的功能。
同样,消息数组是临界资源,所以,用到了synchronized(serverThread.messages)方法,判断该消息为下线功能,则将根据ID删除Vector中的ClientThread线程。
源代码如下:
Thread.sleep(200);
}catch(InterruptedExceptione){
synchronized(serverThread.messages){
if(serverThread.messages.isEmpty()){
continue;
//获取消息队列队首消息
str=(String)this.serverThread.messages.firstElement();
synchronized(serverThread.clients){
System.out.println(serverThread.clients.size());
for(inti=0;
i<
serverThread.clients.size();
i++)
//获取该客户端线程
clientThread=(ClientThread)serverThread.clients.elementAt(i);
try{
clientThread.out.writeUTF(str);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
//从消息队列中删除该消息
this.serverThread.messages.remove(str);
3.2.5DoDataBase类
该类有两个方法AddMsg()和getConnection()方法,其中getConnection()方法用于获取数据库ChatDemo的连接句柄。
AddMsg()方法用于对ChatDemo中的表messages进行写操作。
实现代码如下:
publicclassDoDataBase{
publicvoidAddMsg(Stringtime,StringCatgory,StringOrgID,StringGoalID,Stringcontent)
throwsException{
//打开连接
Connectionconn=getConnection();
//执行操作
PreparedStatementpst=conn
.prepareStatement("
insertintomessagesvalues(?
?
)"
);
pst.setString(1,time);
//时间
pst.setString(2,Catgory);
//消息种类
pst.setString(3,OrgID);
//源地址
pst.setString(4,GoalID);
//目的地址
pst.setString(5,content);
//内容
pst.execute();
//关闭数据库
conn.close();
privateConnectiongetConnection()throwsClassNotFoundException,SQLException{
Class.forName("
net.sourceforge.jtds.jdbc.Driver"
Connectionconn=DriverManager.getConnection("
jdbc:
jtds:
sqlserver:
//localhost:
1433/ChatDemo"
"
sa"
returnconn;
3.3客户端功能实现
图3.1客户端界面
其源代码如下:
publicclassChatClientActivityextendsActivityimplementsRunnable{
privateEditTextusernameEdit,ipEdit,historyEdit,messageEdit;
privateButtonloginButton,leaveButton,sendButton;
privateStringusername,ip,chat_txt,chat_in;
publicstaticfinalintPORT=8521;
//端口号
publicDataInputStreamin=null;
publicDataOutputStreamout=null;
publicSocketsocket;
publicThreadthread;
publicbooleanflag=false;
//标识是否登陆,true为已登录,false为未登录
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
usernameEdit=(EditText)findViewById(R.id.username);
ipEdit=(EditText)findViewById(R.id.ip);
historyEdit=(EditText)findViewById(R.id.history);
messageEdit=(EditText)findViewById(R.id.message);
loginButton=(Button)findViewById(R.id.LoginButton);
leaveButton=(Button)findViewById(R.id.leave);
sendButton=(Button)findViewById(R.id.sendButton);
loginButton.setOnClickListener(listener);
leaveButton.setOnClickListener(listener);
sendButton.setOn
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 聊天室 设计