Socket 多人聊天室的实现 (含前后端源码讲解)(一)

近期工作在小程序、网页中使用了WebSocket,浏览了各个公司对Android人才需求条件中有着要求使用过WebSoket、Socket的条件,便想着在Android上使用Socket来实现聊天室的功能。于是,这篇文章诞生了。

Socket 多人聊天室的实现系列文章:

  • Socket 多人聊天室的实现 (含前后端源码讲解)(一)
  • Socket 多人聊天室的实现(App后台接收消息的处理)(二)

目录

  • 关于Socket
  • 建立连接
    • 服务端
        • 1.创建Socket,bind()绑定地址,listen()监听套接字
        • 2.accept()监听连接
        • 3.read()读数据
        • 4.write()写数据
        • 5.close()关闭连接
    • 客户端
        • 1. 创建Socket、connect()连接Socket
        • 2. write()写数据
        • 3. read()读数据
        • 4. close()关闭连接
  • 效果图

关于Socket

  • 简介
    Socket,又称套接字,在TCP/IP协议分层架构中,属应用层和传输层之间的一个抽象层(也有的说是属于传输层),它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。

Socket 多人聊天室的实现 (含前后端源码讲解)(一)_第1张图片

  • 优点
    1、传输数据时间短,性能高
    2、可以加密,数据安全性强
    3、适合客户端和服务器端之间信息实时交互
    4、传输数据为字节级,传输数据可自定义,数据量小
  • 缺点
    1、相对于http协议传输,增加了开发量

建立连接

Socket 多人聊天室的实现 (含前后端源码讲解)(一)_第2张图片

服务端

1.创建Socket,bind()绑定地址,listen()监听套接字

ServerSocket只需要一行代码就可以完成创建、绑定、监听Socket,绑定的地址没填默认就是本机的ip(在源码中InetAddress.anyLocalAddress()方法得出的结论),监听Socket监听的是改Socket的最大连接数,如果队列满时,会出现提示,并拒绝连接(源码的listen(int backlog)方法这样解释)。

ServerSocket server = new ServerSocket(端口号);

2.accept()监听连接

accept()方法侦听要与ServerSocket建立的连接并接受它。该方法会阻塞,直到建立连接。

server.accept();

3.read()读数据

accept()方法连接成功,会返回Socket对象,通过这一个对象,我们可以实现与客户端的互动,互动的过程涉及到对Socket的writeread,还是建议创建一个线程池,在线程中对Socket的writeread进行操作。

BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), Config.TRANSFER_MESSAGE_CHARSET_NAME));
try {
	String receiveMsg = null;
    while (true) {
        // 循环接收、读取客户端发送过来的信息
        if ((receiveMsg = reader.readLine()) != null) {
            // receiveMsg 接收到的消息
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

在上面的代码中,使用while开启一个死循环,这时候可千万不要理解为这串代码一直在执行着while循环判断receiveMsg 是否为nullreadLine()方法里,有一个地方会执行到一个read(char cbuf[], int off, int len)方法,源码是这样介绍这个方法的:

Reads characters into a portion of an array. This method will block until some input is available, an I/O error occurs, or the end of the stream is reached
将字符读入数组的一部分。此方法将阻塞,直到某些输入可用、发生 IO 错误或到达流末尾

因此,readLine()没有接收到字符,会被readLine()方法里面的read(char cbuf[], int off, int len)方法阻塞,直到接收到字符,继续往下执行,执行完,重新开始while循环。

4.write()写数据

PrintWriter(Writer out,boolean autoFlush)构造方法autoFlush参数用于设置是否自动冲洗(自动发送消息给客户端),如果设为false,调用println(String x)方法后还需要再调用flush()方法才可实现推送消息给客户端,设置为true,直接调用println(String x)方法即可实现将数据写入并发送给用户端.

PrintWriter printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), Config.TRANSFER_MESSAGE_CHARSET_NAME)), true);
printWriter.println(String x);

5.close()关闭连接

关闭连接,也要顺带把与用户的Socket连接也给关闭掉

// 方法一:
socket.close(); // 关闭指定客户端的连接
reader.close(); // 关闭阅读器
server.close(); // 关闭ServerSocket
// 方法二:
// 接收客户端的消息,如果消息为约定好的断开连接的消息,则断开连接

客户端

1. 创建Socket、connect()连接Socket

在Android,访问网络都需要加上网络访问权限

<uses-permission android:name="android.permission.INTERNET"/>

客户端创建Socket,new Socket(String host, int port);需要抛出异常,当IP地址错误、端口号错误、服务器ServerSocket未启动时,都会抛出异常,即连接失败。

try {
	Socket socket = new Socket(String host, int port);
} catch (Exception e) {}

2. write()写数据

同服务器的write()用法

3. read()读数据

同服务器的read()用法

4. close()关闭连接

// 方法一:
socket.close();
// 方法二:
// 给服务器发送相关消息,由服务器断开与指定客户端的连接

效果图

Socket 多人聊天室的实现 (含前后端源码讲解)(一)_第3张图片


点击前往下载Socket 多人聊天室的实现 (含前后端源码详解)(一)源码


参考文档:
网络分层架构(七/四层协议)
Android:这是一份很详细的Socket使用攻略

你可能感兴趣的:(Android,android,java,socket,聊天室,多人聊天)