版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、仔仔细细手把手教你如何写一个Android聊天室,你一定能懂 今天,我们来讲Android聊天室实例开发项目,通过此项目来帮助我们了解Socket网络编程,希望对大家有所帮助。开发之前,我们有必要了解下一些基本知识如下:1、 服务器端ServerSocket:它常用的构造函数是ServerSocket(int port),该构造函数创建的ServerSock对象可以将这个ServerSocket绑定到一个指定的端口上,通过该程序所在计算机的IP地址以及这个端口号,客户端Socket才能连接该ServerSocket。2、 客户端Socket:它常用的简单构造函数是Socket(String h
2、ost,int port),该构造函数根据两个参数连接指定的主机地址和端口号上运行的服务器程序。注意:在创建Socket时如果发生错误,将产生IOException,在程序中必须对之进行处理。所以在创建Socket或ServerSocket时,必须捕获或抛出异常。Socket常用的方法还有以下几种:(1)、getInputStream():返回套接字的输入流,通过得到的输入流可以获取信息。(2)、getOutputStream():返回此套接字的输出流,通过得到的输出流可以输出信息。关闭Socket的方法: 每一个Socket存在时,都讲占用一定的资源,在Socket对象使用完毕时,将其关闭。
3、关闭Socket可以调用Socket的Close()方法。在关闭Socket之前,应将与Socket相关的所有的输入/输出流全部关闭,以释放所有的资源。而且要注意关闭的顺序,与Socket相关的所有的输入/输出流该首先关闭,然后再关闭Socket。Socket通信的一般过程:(1)、服务器端程序创建一个ServerSocket,然后调用accept()方法等待客户连接。(2)、客户端程序创建一个Socket并请求与服务器程序建立连接。(3)、服务器端程序接受客户端的连接请求,并创建一个新的Socket与该客户建立专线连接。(4)、建立了连接的客户端及服务端的两个Socket在一个由服务器端程序
4、创建的单独的线程上对话,对话的方式采用getInputStream()、getOutputStream()得到的输入与输出流进行读取与输出。(5)、服务器端开始等待新的连接请求,重复(2)(5)的过程。 好了,我们有了上面的基础之后之后,我们就开始我们的Socket聊天室编程之旅吧。 首先,我们要了解下,我们这个项目的整天框架,聊天室主要包括两部分:1、服务器端。2、客户端;对于服务器端,我们在PC上采用纯java设计图形界面,而客户端主要是手机客户端。下面我们就开始编写服务器端界面设计程序。1、 新建一个Java项目,命名为PCChat,在该项目中,新建一个java类,命名为Server.j
5、ava,这就是PC服务器端的主界面。2、 主界面截图如下:3、 主界面代码如下:html view plaincopypackage com.wyf.wpf; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; imp
6、ort javax.swing.JTextArea; public class Sever extends JFrame implements ActionListener / 声明两个布局 BorderLayout borderLayout1 = new BorderLayout(); BorderLayout borderLayout2 = new BorderLayout(); / 创建面板和按钮 JPanel jPanel1 = new JPanel(); JPanel jPanel2 = new JPanel(); JButton jButton1 = new JButton();
7、JButton jButton2 = new JButton(); JScrollPane jScrollPane1 = new JScrollPane(); / 创建服务器端接受消息文本框 static JTextArea jTextArea = new JTextArea(); / 声明ServerThread线程类对象 ServerThread serverThread; / 构造函数,用于初始化面板 public Sever() getContentPane().setLayout(borderLayout1); jButton1.setText(启动服务器); jButton1.ad
8、dActionListener(this); jButton2.setText(关闭服务器); jButton2.addActionListener(this); this.getContentPane().add(jPanel1, BorderLayout.NORTH); jPanel1.add(jButton1); jPanel1.add(jButton2); jTextArea.setText(); jPanel2.setLayout(borderLayout2); jPanel2.add(jScrollPane1, BorderLayout.CENTER); jScrollPane1.
9、getViewport().add(jTextArea); this.getContentPane().add(jPanel2, BorderLayout.CENTER); this.setSize(400, 400); this.setVisible(true); / 服务器界面中按钮事件处理 Override public void actionPerformed(ActionEvent e) / TODO Auto-generated method stub if (e.getSource() = jButton1) serverThread = new ServerThread();
10、serverThread.start(); else if (e.getSource() = jButton2) serverThread.finalize(); this.setVisible(false); / 主函数 public static void main(String agrs) Sever sever = new Sever(); sever.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 在该界面中,我们定义了两个按钮分别用于启动服务器和关闭服务器,还有一个文本框用于服务器端接受信息。至于这个界面,用java设计,应该不陌生吧
11、。 好了,今天就到这里,下节我们要讲,如何启动服务器。敬请关注,谢谢。 我们编写的服务器端程序一共包括四个类,其名称及功能如下:Server.java:服务器端主程序负责界面,以及服务端主程序ServerThread的启动,服务端主程序ServerThread又产生BroadCaset及ClientThread线程。BroadCast.java:服务器向客户端广播线程,负责向客户端发送消息。ClientThread.java:维持服务器与单个客户端的连接线程,负责接收客户端发来的信息。ServerThread.java:服务器监听端口线程,负责创建服务器端ServerSocket以及监听是否有
12、新客户端连接,并且记录客户端连接以及需要发送的信息。 上节我们设计好了启动和关闭服务器界面,这节我们主要来讲,如何启动和关闭服务器。当Server.java文件被运行时,首先执行main方法中的代码,创建一个Server类,生成了服务器端的界面,当单击界面上得“启动服务器”按钮时,回创建一个ServerThread对象,并执行该对象中run方法的代码,所以在这里我们通过ServerThread线程来启动和关闭服务器。下面,就来设计该类的实现。1、 首先看当单击启动服务器按钮后的界面运行效果,截图如下:从该界面中,我们可以看到,当我们单击“启动服务器”按钮时,文本框中回出现当前的本地连接IP地址
13、及我们设置的端口号。2、 实现效果代码如下: html view plaincopypackage com.wyf.wpf; import java.io.IOException; import .InetAddress; import .ServerSocket; import .Socket; import .UnknownHostException; import java.util.Vector; /*服务器监听端口线程*/ public class ServerThread extends Thread / 指定服务器监
14、听端口常量 private static final int PORT = 8521; / 声明ServerSocket类对象 ServerSocket serverSocket; /* * 创建一个Vector对象,用于存储客户端连接的ClientThread对象。 * ClientThread类维持服务器与单个客户端的连接线程,负责接收客 * 户端发来的信息,这里为什么使用Vector。因为Vector有自动排序递增功能 */ Vector clients; / 创建一个Vector对象,用于存储客户端发送过来的信息 Vector messages; / 声明BroadCast类,负责服务
15、器向客户端广播信息 BroadCast broadcast; / 声明两个变量,用于获取本地连接IP地址 String ip; InetAddress myIPAddress = null; public ServerThread() /* * 创建两个恶Vector数组非常重要。clients负责存储所有与服务器建立连接 * 的客户端。message负责存储服务器接收到的未发送出去的全部客户端的信息 */ clients = new Vector(); messages = new Vector(); try serverSocket = new ServerSocket(PORT); ca
16、tch (IOException e) try myIPAddress = InetAddress.getLocalHost(); catch (UnknownHostException e) System.out.println(e.toString(); / 获取本地连接地址 ip = myIPAddress.getHostAddress(); / 将该地址信息加入到jTextArea中 Sever.jTextArea.append(服务器地址: + ip + 端口号: + String.valueOf(serverSocket.getLocalPort() + n); / 启动播放消息线
17、程,用于向客户端发送消息 broadcast = new BroadCast(this); broadcast.start(); / 运行线程 Override public void run() / TODO Auto-generated method stub super.run(); while (true) try / 在服务端获取客户端socket Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress().getHostAddress(); / 创建客户端线程并启动 Client
18、Thread clientThread = new ClientThread(socket, this); clientThread.start(); / 如果不为空,则将其添加到clients数组中 if (socket != null) synchronized (clients) clients.addElement(clientThread); catch (IOException E) System.out.println(发生异常: + E); System.out.println(建立客户端联机失败!); System.exit(2); / 关闭服务端socket public
19、void finalize() try serverSocket.close(); catch (IOException E) serverSocket = null; 讲解: 当该类的对象被创建之时,首先创建两个数组,分别用来保存ClientThread对象和消息对象。之后创建一个ServerSocket。创建BroadCast对象,并且启动了该对象线程,即调用了该对象的run()方法,用以不断地向客户端发送消息。当该类的线程被开启后,不断获取得新的客户端,并且将客户端封装在ClientThread之中,然后存于数组当中。开启了ClientThread的线程,用以监听客户端是否有消息。上面开
20、发了启动与关闭服务器端线程程序,下面我们继续开发服务端程序。其实剩下的两个线程CilentThread与BroadCast很好理解,前者就是从客户端读取信息;后者就是服务端想客户端定时发送信息。只要把这两点看懂了,程序就不能。好了,我就直接上代码了:1、ClientThread.java代码如下:html view plaincopypackage com.wyf.wpf; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .So
21、cket; public class ClientThread extends Thread / 声明客户端socket Socket clientSocket; / 声明客户端数据输出与输入流 DataInputStream in = null; DataOutputStream out = null; / 服务端线程 ServerThread serverThread; / 构造函数,初始化相关变量 public ClientThread(Socket socket, ServerThread serverThread) this.clientSocket = socket; this.s
22、erverThread = serverThread; try in = new DataInputStream(clientSocket.getInputStream(); out = new DataOutputStream(clientSocket.getOutputStream(); catch (IOException e2) System.out.println(发生异常 + e2); System.out.println(建立I/O通道失败!); System.exit(3); Override public void run() / TODO Auto-generated me
23、thod stub super.run(); while (true) try / 读取客户端输入数据 String message = in.readUTF(); synchronized (serverThread.messages) if (message != null) / 添加数据到服务端显示 serverThread.messages.addElement(message); Sever.jTextArea.append(message + n); catch (IOException E) break; 讲解: 当该类的构造方法被调用时,获得了Socket得输入与输出流,向客户
24、端发送数据或接受客户端数据。Run()方法监听Socket是否有新消息,如果有新消息,则加入messages数组中。2、编写BroadCast.java,代码如下:html view plaincopypackage com.wyf.wpf; import java.io.IOException; public class BroadCast extends Thread / 声明服务、客户端线程 ClientThread clientThread; ServerThread serverThread; / 字符串 String str; / 构造函数 public BroadCast(Ser
25、verThread serverThread) this.serverThread = serverThread; / 运行 Override public void run() / TODO Auto-generated method stub super.run(); while (true) try Thread.sleep(200); catch (InterruptedException E) synchronized (serverThread.messages) if (serverThread.messages.isEmpty() continue; / 取得消息 str =
26、(String) this.serverThread.messages.firstElement(); / 同步发送消息到各个客户端 synchronized (serverThread.clients) for (int i = 0; i serverThread.clients.size(); i+) / 取得各个客户端 clientThread = (ClientThread) serverThread.clients .elementAt(i); try / 客户端中写入数据 clientThread.out.writeUTF(str); catch (IOException E) t
27、his.serverThread.messages.removeElement(str); 讲解: 该类的run()方法每隔200ms执行一次,向所有客户端发送messages数组中尚未发送出得消息。好了服务端程序就到此开发完毕了。我们的Android聊天室也告一段落了。下面要开发的就是手机客户端。敬请期待,谢谢!呵呵,放了一长假回来了!期待已久的假期结束了。趁着这闲工夫来完结这Android聊天室的开发。好了,让我们开始吧。在(四)中,我们已经把服务端的程序开发完毕了!自我感觉讲的蛮详细的!接下来要开发的就是Android手机客户端了。先来看下客户端运行界面吧,截图如下:界面效果就是这样,简
28、单吧。下面我们就来开发这个项目的客户端。1、创建一个Android项目,命名为ChatAndroidClient;2、编写布局文件,这个布局应该难不倒大家,直接上代码,如下:html view plaincopy 3、编写主程序Activity,具体代码如下:html view plaincopypackage com.wyf.wpf; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .InetAddress; import j
29、.NetworkInterface; import .Socket; import .SocketException; import .UnknownHostException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import an
30、droid.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class ChatAndroidClientActivity extends Activity implements OnClickListener, Runnable /声明登录名、ip地址、消息对话框、信息 private Edi
31、tText usernameEdit; private EditText ipEdit; private EditText historyEdit; private EditText messageEdit; /声明登陆、发送、离开等按钮 private Button loginButton; private Button sendButton; private Button leaveButton; /声明用户名、ip地址、聊天内容、信息输入等字段 private String username,ip,chat_txt,chat_in; private static final int PO
32、RT=8521; /客户端socket用于向服务器发送信息 Socket socket; /线程,及时更新信息框中内容 Thread thread; /声明客户端数据输入输出流 DataInputStream in; DataOutputStream out; /是否登陆的标志 boolean flag=false; /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState)
33、; setContentView(R.layout.main); /初始化相关编辑框对象 usernameEdit=(EditText)findViewById(R.); ipEdit=(EditText)findViewById(R.id.ip); ipEdit.setText(97); historyEdit=(EditText)findViewById(R.id.history); messageEdit=(EditText)findViewById(R.id.message); /初始化按钮并注册相关单击事件 loginButton=(Button)
34、findViewById(R.id.login); loginButton.setOnClickListener(this); leaveButton=(Button)findViewById(R.id.leave); leaveButton.setOnClickListener(this); sendButton=(Button)findViewById(R.id.send); sendButton.setEnabled(false);/设置不可用 sendButton.setOnClickListener(this); /按钮单击事件处理 Override public void onCl
35、ick(View v) / TODO Auto-generated method stub switch(v.getId() case R.id.login:/登陆 login(); break; case R.id.leave:/退出 leave(); break; case R.id.send:/发送 send(); break; /登陆函数 public void login() username=usernameEdit.getText().toString(); ip=ipEdit.getText().toString(); if(username!=null&!username.e
36、quals()&username!=用户输入&ip!=null) try /构建客户端Socket对象 socket=new Socket(ip,PORT); /创建客户端输入输出流,用于对服务器发送或接受数据 in=new DataInputStream(socket.getInputStream(); out=new DataOutputStream(socket.getOutputStream(); /得到当前事件 Date now=new Date(System.currentTimeMillis(); /设置事件显示格式 SimpleDateFormat format=new SimpleDateFormat(hh:mm:ss
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宣化科技职业学院《劳动与社会保障法》2025-2026学年期末试卷
- 2026道德与法治四年级拓展空间 消防安全法规
- 义诊健康宣教服务-1
- 2024年公司食堂工作总结
- 2021年武汉枫叶学校小升初语文模拟题及答案
- 2024年《济南的冬天》教案课件
- 2021年开放本科现代管理专题模拟题一
- 氰(CAS号:460-19-5)理化性质与危险特性一览表
- 职业病防治法健康科普
- 质量、环境、职业健康安全管理体系试卷(普工)
- 招5人!海南州2026年第一季度公开招录编外临聘人员建设笔试模拟试题及答案解析
- 呼吸抢救室工作制度
- 2026中国邮政储蓄银行黑龙江省分行春季校园招聘考试参考试题及答案解析
- 2026云南省投资控股集团有限公司集中招聘笔试参考题库及答案解析
- BCG -2026效率之后中国医药创新的价值攀登研究报告
- 配件采购流程制度
- 2026年安全生产风险预防与应对培训试卷及答案
- 2026年春江酒城嘉苑“楼上养老 楼下医疗”CCRC社区运营模式解析
- 继电保护员道德知识考核试卷含答案
- 人教版(2026)三年级下册美术第三单元第1课《皮影的生命力》课件
- 2026年国际对外汉语考试题库及答案
评论
0/150
提交评论