由于之前写了一个聊天软件是使用轮询的方式获取服务器数据感觉不是太及时,所以最近花了一些时间去学习关于通讯方面的知识。做了一个通讯的客户端和服务器端,具体工作就是在客户端与服务器之间建立一个长连接,当服务器接收到客户端发来的消息时分发给所有连接设备。
————————————后台程序————————————
1,建立服务器(MyServer.java)
// 1,创建服务端对象
ServerSocket serverSocket = new ServerSocket(10010);
System.out.println("Server Running.....");
while (true) {
//阻塞方法
Socket s = serverSocket.accept();
//存入缓存
CacheHelper.connCache.put(s.getInetAddress().getHostAddress(), s);
System.out.println(s.getInetAddress().getHostAddress()+":connect in");
// 开子线程给去处理
new Thread(new SocketServerThread(s)).start();
}
2,当获取到一个连接进来的Socket时,开启一个子线程去单独处理
(SocketServerThread.java)
public class SocketServerThread implements Runnable {
private Socket s;
public SocketServerThread(Socket s) {
super();
this.s = s;
}
@Override
public void run() {
try {
BufferedReader bufin = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String receiveMsg = null;
while ((receiveMsg = bufin.readLine()) != null) {
String sendIP = s.getInetAddress().getHostAddress();
String dispatchMsg = sendIP+":"+receiveMsg;
System.out.println("dispatchMsg="+dispatchMsg);
new Thread(new DispatchMsg(dispatchMsg)).start();
}
// 关闭资源
s.close();
} catch (Exception e) {
}
}
}
3,在子线程中如果获取到消息,则开启线程去把这条消息分发给缓存中的所有连接用户(DispatchMsg.java)
public class DispatchMsg implements Runnable {
private String disMsg;
public DispatchMsg(String disMsg) {
super();
this.disMsg = disMsg;
}
@Override
public void run() {
Set<Map.Entry<String,Socket>> set = CacheHelper.connCache.entrySet();
Iterator<Map.Entry<String,Socket>> it = set.iterator();
while(it.hasNext()){
Map.Entry<String,Socket> en =it.next();
try {
PrintWriter pw = new PrintWriter((en.getValue()).getOutputStream(),true);
pw.println(disMsg);
} catch (Exception e) {
}
}
}
}
4,存储所有连接的socket的类(CacheHelper.java)
public class CacheHelper {
public static final Map<String,Socket> connCache =new HashMap<String,Socket>();
}
————————————安卓客户端————————————
1,存储与数据库连接的类(Helper.java)
主要贴出两个主要的程序,其他细节会在文件附录中给到
/**
* Des:帮助类
* mySocket:存放与服务器建立连接的Socket
* socketReader:输入流
* socketWriter:输出流
* showData:页面显示数据
*/
public class Helper {
public static Socket mySocket;
public static BufferedReader socketReader;
public static PrintWriter socketWriter;
public static final List<ChatroomMessage> showData = new ArrayList<ChatroomMessage>();
}
2,建立与服务器的链接类(IniSocket.java)
/**
* Des:启动应用后初始化与服务器之间的Socket链接
*
* Helper.mySocket = new Socket("ip地址",10010);
* 需要做修改,把ip地址设置为服务器的对应ip,
* 并且服务器与客户端需要再同一wifi环境下
*/
public class IniSocket implements Runnable{
@Override
public void run() {
//开启Socket
try {
//服务器的ip地址和端口号
Helper.mySocket = new Socket("192.168.100.114",10010);
//读取信息
Helper.socketReader =
new BufferedReader(new InputStreamReader(Helper.mySocket.getInputStream()));
//输出信息
Helper.socketWriter = new PrintWriter(Helper.mySocket.getOutputStream(),true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:https://github.com/ReeseLin/SocketMsg.git
后台程序:https://github.com/ReeseLin/SocketServer.git