java server 多client异步socket通信demo
来源:互联网 发布:云计算的安全问题 编辑:程序博客网 时间:2024/06/05 07:13
本demo打包下载,请点击这里
本demo主要用java实现了服务器监听多客户端登录,并实现了客户端与服务器的异步socket通信,通信过程采用了消息队列缓冲机制(生产者消费者模式)。
登录过程是后来写的,用的是同步模式。密码验证采用的是和用户名相同为验证pass,可以根据需要修改。
登录3次失败后,服务器会断开该客户端的socket,客户端退出,需重新启动客户端。
登录成功后,客户端需要记住自己的id,这块忘写了。可以由服务器返回id,也可以输入id时记录(同一个地方输入,注意不要把密码当成id记录了)。
没有写客户端之间的通信,可以使用MsgPacket将发送和接收客户端id打包发给服务端,在服务端解包后,通过map和id找到接收客户端的socket,将信息发送过去。
本demo服务端可以向所有客户端发送推送消息。
本demo是在ubuntu环境下写的,用javac java命令即可编译运行。
打包资源里面有makefile,通过执行make可以编译,make runs 可以运行服务端,make runc 可以运行客户端。
没有心跳机制,可以参考 http://my.oschina.net/fengcunhan/blog/178155
下面是关键的代码。
SocketUtil.java 通信过程中的socket管理,采用了消息队列机制,并开启了Sender和Receiver两个线程处理发送和接收消息。
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.ArrayList;import java.util.List;public class SocketUtil { public static final String MSG_QUIT = "quit"; private Socket mSocket; private MsgQueue<String> mMsgQueue = new MsgQueue<String>(); public SocketUtil(Socket socket) { mSocket = socket; new Thread(new Sender(), "Sender").start(); new Thread(new Receiver(), "Receiver").start(); } private class MsgQueue<T> { private static final int CAPACITY = 10; private List<T> mMsgs = new ArrayList<T>(); public synchronized void push(T msg) { try { while (mMsgs.size() >= CAPACITY) { wait(); } mMsgs.add(msg); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized T pop() { T msg = null; try { while (mMsgs.size() <= 0) { wait(); } msg = mMsgs.get(0); mMsgs.remove(0); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } return msg; } } private class Sender implements Runnable { @Override public void run() { System.out.println("Sender ... start --- " + Thread.currentThread().getName()); try { PrintWriter out = new PrintWriter(mSocket.getOutputStream(),true); String msg = ""; while (!(msg = mMsgQueue.pop()).equals(MSG_QUIT)) { onMsgSendStart(msg); out.println(msg); onMsgSendEnd(msg, true); } out.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("Sender ... end --- " + Thread.currentThread().getName()); } } private class Receiver implements Runnable { @Override public void run() { System.out.println("Receiver ... start --- " + Thread.currentThread().getName()); try { BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream())); String msg = ""; while ((msg = in.readLine()) != null){ onMsgReceived(msg); } in.close(); pushMsg(MSG_QUIT);//quit sender onSocketClosedRemote(); } catch (IOException e) { //e.printStackTrace(); onSocketClosedSelf(); } System.out.println("Receiver ... end --- " + Thread.currentThread().getName()); } } public final void pushMsg(String msg) { mMsgQueue.push(msg); } public final void quit() { pushMsg(MSG_QUIT);//quit sender try { if (mSocket != null) { mSocket.close(); mSocket = null; } } catch (IOException e) { e.printStackTrace(); } } public final Socket getSocket() { return mSocket; } private void onSocketClosedSelf() { } protected void onSocketClosedRemote() { } protected void onMsgSendStart(String msg) { } protected void onMsgSendEnd(String msg, boolean success) { } protected void onMsgReceived(String msg) { } protected void onMsgInput(String msg) { }}MyServer.java
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class MyServer { private static final int PORT = 9876; private static final int MAX_CLIENT_COUNT = Integer.MAX_VALUE; private ServerSocket mSS; private Map<String, Client> mClients = new HashMap<String, Client>(); public MyServer() { try { mSS = new ServerSocket(PORT); } catch (IOException e) { e.printStackTrace(); } } public void startServer() { new Thread(new PushThread(), "PushThread").start(); try { while (mClients.size() < MAX_CLIENT_COUNT) { Socket socket = mSS.accept(); new Thread(new LoginThread(socket), "LoginThread").start(); } } catch (IOException e) { e.printStackTrace(); } } private class LoginThread implements Runnable { private static final int MAX_TRY = 3; private Socket mSocket; public LoginThread(Socket socket) { mSocket = socket; } @Override public void run() { System.out.println("LoginThread ... start --- " + Thread.currentThread().getName()); String id = waitForLogin(); if (id != null) { Client client = new Client(mSocket, id); mClients.put(id, client); System.out.println("A new socket(" + mSocket + ") connected." + " Client size: " + mClients.size());// tellAllClientChanged(); } else { try { mSocket.close(); mSocket = null; } catch (IOException e) { e.printStackTrace(); } } System.out.println("LoginThread ... end --- " + Thread.currentThread().getName()); } private String waitForLogin() { String loginId = null; try { BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream())); PrintWriter out = new PrintWriter(mSocket.getOutputStream(),true); for (int i = MAX_TRY; i > 0; i--) { out.println("Login: you can try " + i + " times."); out.println("Please input your id:"); String id = in.readLine(); if (!isUserExist(id)) { out.println("User (" + id + ") not exist!"); continue; } out.println("Please input your password:"); String pwd = in.readLine(); if (!isPwdCorrect(id, pwd)) { out.println("Password error!"); continue; } if (isRepeatLogin(id)) { out.println("User (" + id + ") is already online!"); continue; } else { loginId = id; break; } } //in.close();//do not close here if (loginId == null) { out.println("I'm so sorry! Login failed!"); } else { out.println("Welcome " + loginId + "! Login success!"); } } catch (IOException e) { //e.printStackTrace(); } return loginId; } private boolean isUserExist(String id) { return true;//TODO } private boolean isPwdCorrect(String id, String pwd) { return (id.equals(pwd));//TODO } private boolean isRepeatLogin(String id) { return mClients.containsKey(id); } }// private void tellAllClientChanged() {// Iterator<String> iterator = mClients.keySet().iterator();// while (iterator.hasNext()) {// String id = iterator.next();// Client client = mClients.get(id);// Socket socket = client.getSocket();// String ip = socket.getInetAddress().toString();// int port = socket.getPort();// pushMsgToAllClient("-------------["+id+"]" + ip + ":" + port);// }// } class Client extends SocketUtil { private String mId; public Client(Socket socket, String id) { super(socket); mId = id; } @Override protected void onMsgSendStart(String msg) { System.out.println("to <" + mId + ">: " + msg); } @Override protected void onMsgReceived(String msg) { System.out.println("[" + mId + "]: " + msg); pushMsg("Your msg is: " + msg); } protected void onSocketClosedRemote() { mClients.remove(mId); System.out.println("Client (" + mId + ") offline. Client size: " + mClients.size());// tellAllClientChanged(); } } private class PushThread implements Runnable { @Override public void run() { System.out.println("PushThread ... start --- " + Thread.currentThread().getName()); try { BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in)); String msg = ""; while (!(msg = sysIn.readLine()).equals(SocketUtil.MSG_QUIT)) { pushMsgToAllClient(msg); } sysIn.close(); closeServer(); } catch (IOException e) { e.printStackTrace(); } System.out.println("PushThread ... end --- " + Thread.currentThread().getName()); } } private void pushMsgToAllClient(String msg) { Iterator<String> iterator = mClients.keySet().iterator(); while (iterator.hasNext()) { String id = iterator.next(); Client client = mClients.get(id); System.out.println("push message to [" + id + "]" + client); client.pushMsg(msg); } } private void closeServer() { Iterator<String> iterator = mClients.keySet().iterator(); while (iterator.hasNext()) { String id = iterator.next(); Client client = mClients.get(id); System.out.println("Close [" + id + "]" + client); client.quit(); } try { mSS.close(); } catch (IOException e) { e.printStackTrace(); } }}MyClient.java
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;public class MyClient { private static final String SEVER_IP = "127.0.0.1"; private static final int SEVER_PORT = 9876; private Socket mSocket; private ClientSocketUtil mSocketUtil; public MyClient() { try { mSocket = new Socket(SEVER_IP, SEVER_PORT); System.out.println("My socket: " + mSocket); } catch (IOException e) { e.printStackTrace(); } } public void connect() { new Thread(new PushThread(), "PushThread").start(); mSocketUtil = new ClientSocketUtil(mSocket); } private class ClientSocketUtil extends SocketUtil {//TODO socket from who to who public ClientSocketUtil(Socket socket) { super(socket); } @Override protected void onMsgSendStart(String msg) { System.out.println("[ME]: " + msg); } @Override protected void onMsgReceived(String msg) { System.out.println("[SERVER]: " + msg); } @Override protected void onSocketClosedRemote() { socketClosedRemote = true; System.out.println("Remote socket closed, input any words to quit."); } } private boolean socketClosedRemote = false; private class PushThread implements Runnable { @Override public void run() { System.out.println("PushThread ... start --- " + Thread.currentThread().getName()); try { BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in)); String msg = ""; while (!socketClosedRemote && !(msg = sysIn.readLine()).equals(SocketUtil.MSG_QUIT)) { mSocketUtil.pushMsg(msg); } sysIn.close(); mSocketUtil.quit(); } catch (IOException e) { e.printStackTrace(); } System.out.println("PushThread ... end --- " + Thread.currentThread().getName()); } }}完整code打包下载:http://download.csdn.net/detail/kingodcool/8747149
0 0
- java server 多client异步socket通信demo
- Java Socket编程 多线程server和client通信demo
- vc++ socket通信基础 client and server demo
- 【Little_things】简单的Client/Server通信小程序(java socket)
- Java socket通信Demo
- messenger,client和server通信Demo
- Silverlight Socket异步通信 范例 Demo
- socket demo,实现同步异步通信
- 简单的socket UDP Client Server通信
- socket通信server+client的C++版
- Socket编程—Client、Server通信
- 使用Socket编写Client-Server通信总结
- java socket client-server-client小例子
- Java Client 与C++ Servertcp通信 demo
- nio socket 异步通信 java
- java socket:一个Server对应多个Client
- socket一个server多个client间的通讯学习历程和demo
- Aio--Java异步IO的 Socket Demo
- 《BIG DATA:大数据时代》(维克托·迈尔—舍恩伯格)
- Javascript 时间处理函数
- 解决office套件打开卡顿白屏的问题
- 进击的css!
- OnActionExecuting 中设置跳转指定网址或路由
- java server 多client异步socket通信demo
- 正则表达式的一些匹配规则
- poj 2456
- 庆安身份证号码户籍地址信息查询
- LeetCode的medium题集合(C++实现)十五
- Android Studio如何发布APK
- epoll详解-epoll学习笔记
- QCustomPlot类解读
- 获得不了积分