socket通信例子_服务端写客户端读多线程写法

来源:互联网 发布:winpcap是什么软件 编辑:程序博客网 时间:2024/06/13 23:53
1、主程序
/** * 主程序启动入口 *  * @param args */public static void main(String[] args) {ctx = new ClassPathXmlApplicationContext(APPLICATION_XML_FILE);ctx.start();//SingletonMessagePush instance=SingletonMessagePush.getInstance();//单例服务类try {ServerSocket serverSocket=new ServerSocket(getMessagePushPort());//serverSocket,只负责监听客户端连接,一旦连接成功,服务端会新建一个socket负责与客户端通信while(true){//不断监听客户端连接Socket socket = serverSocket.accept();//返回一个客户端的Socket对象实例//System.out.println("【发现客户端连接>>>>>>】");if(null!=socket){CopyOnWriteArrayList<Socket> oldList=instance.getSocket();        for (Socket so : oldList) {        if(so.isConnected()==false||so.isClosed()==true){        instance.getSocket().remove(so);//移除        System.out.println(so.getInetAddress()+"从socket客户端集合移除。");        }        }        if(socket.isConnected()==true&&socket.isClosed()==false){        instance.getSocket().add(socket);//添加客户端socketSystem.out.println("添加客户端:"+socket.getInetAddress()+",当前有效客户端总数:"+instance.getSocket().size());        }}}} catch (Exception e) {e.printStackTrace();System.out.println("主程序启动时服务端socket异常");}}


2、推送消息单例类
package com.vxichina.cluster.persistence.core;import java.io.OutputStreamWriter;import java.io.Writer;import java.net.Socket;import java.util.concurrent.CopyOnWriteArrayList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** @author mingfeng.wang* @date 2016年3月15日 * @time 上午10:54:18* 向录屏程序推送消息的类*/public class SingletonMessagePush {//有效客户端socket连接集合private CopyOnWriteArrayList<Socket> socket=new CopyOnWriteArrayList<Socket>();//线程池private ExecutorService threadPool=Executors.newCachedThreadPool();//private构造函数private SingletonMessagePush(){}private static SingletonMessagePush instance;//对外访问方法public static SingletonMessagePush getInstance(){if(null==instance){instance=new SingletonMessagePush();}return instance;}/** * 推送消息的主方法 * @param dataStr */public void doMain(String dataStr){try {         if(null!=dataStr&&!"".equals(dataStr)){        if(null!=socket&&socket.size()>0){        //#s 给所有有效连接的客户端推送消息        for (Socket sc : this.getSocket()) {        final String message=dataStr;        final Socket clientSocket=sc;        if(sc.isConnected()==true&&sc.isClosed()==false){        //new Thread(new Task(sc,dataStr)).start();//多线程        Thread.sleep(0);        //线程池方式        threadPool.execute(new Runnable() {@Overridepublic void run() {try {System.out.println("当前线程name="+Thread.currentThread().getName()+",  id="+Thread.currentThread().getId());// 服务端写数据Writer writer = new OutputStreamWriter(clientSocket.getOutputStream());writer.write(message);writer.flush();System.out.println("成功给客户端"+clientSocket.getInetAddress()+"推送消息。消息内容:\n"+message);//writer.close();//不能关闭,关闭会导致客户端close一段时间}catch (Exception e) {System.out.println("给客户端"+clientSocket.getInetAddress()+"推送消息异常。");}}});        }}        //#e}else{System.out.println("暂无客户端连接。");}         }} catch (Exception e) {e.printStackTrace();System.out.println("doMain推送消息异常。");}}public CopyOnWriteArrayList<Socket> getSocket() {return socket;}public void setSocket(CopyOnWriteArrayList<Socket> socket) {this.socket = socket;}}

3、模拟客户端访问
public class ClientSocketTest {public static void main(String[] args) {String host="192.68.19.64";//自定义int port=9080;try {Socket client = new Socket(host, port);while(true){System.out.println("【>>>>>>客户端正在监听>>>>>>】,isConnected="+client.isConnected()+",isClosed="+client.isClosed());// 客户端读数据Reader reader = new InputStreamReader(client.getInputStream());char chars[] = new char[64];int len;StringBuffer sb = new StringBuffer();while ((len = reader.read(chars)) != -1) {sb.append(new String(chars, 0, len));}System.out.println("客户端读数据结束。" );reader.close();//client.close();}}catch(java.net.SocketException e){if(e.getMessage().equals("Connection reset")){System.out.println("连接被重置,服务端已关闭。");}}catch (Exception e) {e.printStackTrace();System.out.println("客户端其它异常。");}}}


===============================================================================
1、服务端监听端口
private static final String appConfigFile = "/app-config.properties";public static void main(String[] args) {SingletonServerSocket singletonServerSocket=SingletonServerSocket.getInstance();try {//System.out.println("端口:"+getMessagePushPort());ServerSocket serverSocket=new ServerSocket(getMessagePushPort());singletonServerSocket.setServerSocket(serverSocket);//serverSocketwhile(true){Socket socket = serverSocket.accept();//监听,接受客户端连接if(null!=socket){singletonServerSocket.setSocket(socket);}}} catch (IOException e) {e.printStackTrace();}}/** * 从Properties文件中获取推送信息需要监听的socket通信端口 * @return */public static int getMessagePushPort(){int port=0;Properties properties = new Properties();try {properties.load(Object.class.getResourceAsStream(appConfigFile));} catch (IOException e) {e.printStackTrace();}    port=Integer.valueOf(properties.getProperty("messagePushPort").trim());return port;}


2、调用
SingletonServerSocket singletonServerSocket=SingletonServerSocket.getInstance();//单例类//推送socket消息到客户端singletonServerSocket.doMain(str.toString());


3、SingletonServerSocket 单例类-服务端写数据
public class SingletonServerSocket {private ServerSocket serverSocket;private Socket socket;//private构造函数private SingletonServerSocket(){}private static SingletonServerSocket instance;//对外访问方法public static SingletonServerSocket getInstance(){if(null==instance){instance=new SingletonServerSocket();}return instance;}/** * 推送消息的主方法 * @param dataStr */public void doMain(String dataStr){try {         if(null!=dataStr&&!"".equals(dataStr)){         if(null!=socket){         new Thread(new Task(socket,dataStr)).start();//多线程}else{System.out.println("暂无客户端连接,无法完成写操作。");}         }} catch (Exception e) {e.printStackTrace();}} /**  * 用来处理socket请求的多线程  *   *  */static class Task implements Runnable {private Socket socket2;private String data;public Task(Socket socket, String data) {this.socket2 = socket;this.data = data;}public void run() {try {handleSocket();// 处理客户端socket} catch (Exception e) {e.printStackTrace();}}/** * 跟客户端Socket进行通信 *  */private void handleSocket(){try {// 服务端写数据Writer writer = new OutputStreamWriter(socket2.getOutputStream());writer.write(data);System.out.println("服务端写数据:" + data);writer.flush();//writer.close();} catch (java.net.SocketException e) {System.out.println("无法找到写数据的客户端!");} catch (Exception e) {System.out.println("服务端写数据错误!");}// socket2.close();//服务端socket,不能关闭}}public ServerSocket getServerSocket() {return serverSocket;}public void setServerSocket(ServerSocket serverSocket) {this.serverSocket = serverSocket;}public Socket getSocket() {return socket;}public void setSocket(Socket socket) {this.socket = socket;}}

4、客户端读数据
public class ClientSocket {public static void main(String[] args) {String host="192........";int port=9099;try {Socket client = new Socket(host, port);while(true){System.out.println("client request...");if(client.isClosed()){client = new Socket(host, port);}// 客户端读数据Reader reader = new InputStreamReader(client.getInputStream());char chars[] = new char[64];int len;StringBuffer sb = new StringBuffer();while ((len = reader.read(chars)) != -1) {sb.append(new String(chars, 0, len));}System.out.println("客户端读数据:" + sb);reader.close();client.close();}} catch (Exception e) {e.printStackTrace();}}}
0 0