Android即时通讯--仿QQ即时聊天:(一)初识Socket

来源:互联网 发布:绫野刚 知乎 编辑:程序博客网 时间:2024/05/17 04:10

1、即时通讯简介

即时通讯(Instant Messaging,简称IM)是一个终端服务,允许两人或者多人通过网络即时传递文字讯息、档案、语音等。简单的概括就是发送消息时,只要对方在线,就能立即接收到消息。即时通讯的底层使用socket实现。即时通讯按使用用途分为企业即时通讯和网站即时通讯,根据装载的对象又可分为手机即时通讯和PC即时通讯,手机即时通讯代表是微信、QQ、短信、陌陌
在这篇文章中,利用Socket+IO流+Thread线程+监听器的知识,简单的实现了点对点的即时通讯,功能比较丑陋,但是底层实现原理是非常重要的,希望这篇文章对初学者能有所帮助,大神勿进、勿喷。
本项目的效果图如下
         
         

2、初识Socket

所谓的Socket通常称为套接字,用于描述IP地址和端口,是一个通信连的句柄。应用程序通过套接字向网络发送请求,或者应答网络请求。Socket套接字,其实就是Java对TCP/IP的实现,Socket和ServerSocket可以形象的比喻为插头和插座,ServerSocket插座提供电源,是服务端;Socket插头要得到电源,是客户端。Socket网络通讯传输数据的过程就好比插头获取插座电源的过程。
服务端:利用ServerSocket监听指定的端口,等待客户端的连接请求,客户端建立连接之后,产生会话,完成会话后,关闭连接。
客户端:利用Socket向网络上的某一个端口发出连接请求,一旦连接成功,产生会话,完成回话之后,关闭连接。
服务端接收消息代码
/** * socket服务端 *  * @author ZHY *  */public class ServerSocketTest {public static void main(String[] args) throws IOException {final ServerSocket server = new ServerSocket(8090);System.out.println("服务器已经启动" + server);// 开启一个线程,时刻监听客户端发送过来的连接请求new Thread() {public void run() {super.run();while (true) {try {Socket client = server.accept();// 服务器接收到链接进来的客户端System.out.println("有客户端链接进来" + client);// 处理接收到的数据// 由于服务器不知道客户端什么时候发送数据过来,所以要创建等待线程,时刻等待处理客户端发送过来的额数据WaitThread waitThread = new WaitThread(client);waitThread.start();} catch (IOException e) {e.printStackTrace();}}}}.start();}// 等待线程public static class WaitThread extends Thread {private Socket client;// 服务端使用输入流读取数据private DataInputStream reader;// 在构造等待线程的时候,给客户端赋值public WaitThread(Socket client) {super();this.client = client;}public void run() {super.run();// 循环等待处理数据while (true) {if (reader == null) {// 根据客户端发来的输入流,创建服务器读取数据的流readertry {reader = new DataInputStream(client.getInputStream());} catch (IOException e) {e.printStackTrace();}}try {String msg = reader.readUTF();System.out.println(msg);} catch (IOException e) {e.printStackTrace();}}}}}
客户端发送消息代码
/** * Socket客户端 * @author ZHY * */public class MainActivity extends Activity {private Button client;private Button send;private Socket socket;private DataOutputStream writer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);client = (Button) findViewById(R.id.client);// 连接服务器send = (Button) findViewById(R.id.send);// 发送数据client.setOnClickListener(new OnClickListener() {public void onClick(View v) {// 连接服务器,与网络有关,要在子线程中new Thread() {@Overridepublic void run() {super.run();try {// 创建socket,连接服务器socket = new Socket("192.168.0.148", 8090);} catch (Exception e) {e.printStackTrace();}}}.start();}});send.setOnClickListener(new OnClickListener() {public void onClick(View v) {// 客户端向服务端发送消息,通过输出流,在子线程中new Thread() {@Overridepublic void run() {super.run();if (socket == null) {// 创建socket,连接服务器try {socket = new Socket("192.168.0.148", 8090);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 已经建立了连接if (writer == null) {try {writer = new DataOutputStream(socket.getOutputStream());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// writer也不是空try {writer.writeUTF("我是客户端发送的数据" + socket);} catch (IOException e) {e.printStackTrace();}}}.start();}});}}
客户端与服务端的数据交互会话示意图

至此,Socket的基本原理已经交代清楚,了解了底层实现的原理,相信对即时通讯的理解将更深一步。
PS:如果有什么不妥的地方希望大神指出,共同学习进步!!!

5 3
原创粉丝点击