近期工作在小程序、网页中使用了WebSocket,浏览了各个公司对Android人才需求条件中有着要求使用过WebSoket、Socket的条件,便想着在Android上使用Socket来实现聊天室的功能。于是,这篇文章诞生了。
Socket 多人聊天室的实现系列文章:
ServerSocket只需要一行代码就可以完成创建、绑定、监听Socket,绑定的地址没填默认就是本机的ip(在源码中InetAddress.anyLocalAddress()
方法得出的结论),监听Socket监听的是改Socket的最大连接数,如果队列满时,会出现提示,并拒绝连接(源码的listen(int backlog)
方法这样解释)。
ServerSocket server = new ServerSocket(端口号);
accept()方法侦听要与ServerSocket建立的连接并接受它。该方法会阻塞,直到建立连接。
server.accept();
accept()方法连接成功,会返回Socket对象,通过这一个对象,我们可以实现与客户端的互动,互动的过程涉及到对Socket的write
、read
,还是建议创建一个线程池,在线程中对Socket的write
、read
进行操作。
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
是否为null
,readLine()
方法里,有一个地方会执行到一个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
循环。
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);
关闭连接,也要顺带把与用户的Socket连接也给关闭掉
// 方法一:
socket.close(); // 关闭指定客户端的连接
reader.close(); // 关闭阅读器
server.close(); // 关闭ServerSocket
// 方法二:
// 接收客户端的消息,如果消息为约定好的断开连接的消息,则断开连接
在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) {}
同服务器的write()
用法
同服务器的read()
用法
// 方法一:
socket.close();
// 方法二:
// 给服务器发送相关消息,由服务器断开与指定客户端的连接
点击前往下载Socket 多人聊天室的实现 (含前后端源码详解)(一)源码
参考文档:
网络分层架构(七/四层协议)
Android:这是一份很详细的Socket使用攻略