在上一篇文章中,我们初步明白了一个socket如何在客户端和服务器端进行通信的过程,客户端和服务器端能够进行简单的通信,这一篇文章,我们将加入多线程通信的部分,这部分在实际工作中是很有用的;上一篇内容,请参考:Android上JAVA Socket通信解析(一)初识socket通信
1. 简介
前面服务器和客户端只是进行了简单的通信操作:服务器端接受客户端的连接请求后,返回一个字符串给客户端;但是在实际的使用过程中,客户端会合服务器端进行长时间的通信,服务器端不断的读取客户端发来的数据,并向客户端写入数据;客户端不断的从服务器读取数据,兵饷服务器端写入数据;
当服务器使用inputstream读取数据的时候,在该方法返回之前,线程被阻塞,程序无法继续执行,故服务器端应该为每个socket单独启动一个线程,每条线程负责与一个客户端进行通信;
同理,客户端读取服务器的数据的线程也会被阻塞,所以客户端应该单独启动一个线程,这个线程专门负责读取服务器数据;
下面模拟一个简单的C/S架构的聊天室应用:服务器端每接收到一个socket请求,就开一个线程与客户端通信,并保存线程到list中,对每个socket请求发送来的数据,都转发输出不到同的socket客户端;
2. 服务器端代码
下面是服务器端代码:一个serversocket监听的类,负责监听客户端的请求,一个负责处理客户端通信的线程类ServerThread,每个线程类ServerThread都有一个回调监听;
服务器端循环监听接受客户端的请求,接收到客户端的请求后,开启一个线程与客户端通信,并将新的线程添加到list中,对于回调,当客户端有消息数据到达服务器端,监听回调方法onMsgArrive,循环线程列表,每个线程发送消息内容给客户端,进行转发,对于不存在的消息从列表list中删除;
public class MyServer
{
private static final String CODE_TYPE = "utf-8";
private static ArrayList<Socket> sockets = new ArrayList<Socket>();
/**
* @Description TODO(描述这个方法的作用)<br/>
* @param args
* void
* @date 2017-8-26
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
try
{
ServerSocket ss = new ServerSocket(4000);
while (true)
{
Socket s = ss.accept();
System.out.println("new socket receive ");
sockets.add(s);
new Thread(new ServerThread(s, clientStatuListner)).start();
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrac