Java Socket实战之一 单线程通信基础socket

现在做Java直接使用Socket的情况是越来越少,因为有很多的选择可选,比如说可以用spring,其中就可以支持很多种远程连接的操作,另外jboss的remoting也是不错的选择,还有Apache的Mina等等,但是在有些时候一些特殊情况仍然逃脱不了直接写Socket的情况,比如公司内部一些莫名其妙的游戏规则。

废话不说了,下面就看看如果自己写Socket应该怎么做吧。

首先是写一个Server类,这个类用来监听10000端口,并从这个端口接收消息然后输出,当收到“bye”时退出。

 

package com.googlecode.garbagecan.test.socket.sample1;  
  
import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.net.ServerSocket;  
import java.net.Socket;  
  
public class MyServer {  
    public static void main(String[] args) throws IOException {  
        ServerSocket server = new ServerSocket(10000);  
        Socket socket = server.accept();  
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
        PrintWriter out = new PrintWriter(socket.getOutputStream());  
          
        while (true) {  
            String msg = in.readLine();  
            System.out.println(msg);  
            out.println("Server received " + msg);  
            out.flush();  
            if (msg.equals("bye")) {  
                break;  
            }  
        }  
        socket.close();  
    }  
}  

然后是一个Client类,这个类连接上面启动的Server类,然后接收任何用户输入,当遇到回车时发送字符串到Server上,当输入“bye”是退出。

 

package com.googlecode.garbagecan.test.socket.sample1;  
  
import java.io.BufferedReader;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.net.Socket;  
  
public class MyClient {  
    public static void main(String[] args) throws Exception {  
        Socket socket = new Socket("localhost", 10000);  
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
        PrintWriter out = new PrintWriter(socket.getOutputStream());  
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
  
        while (true) {  
            String msg = reader.readLine();  
            out.println(msg);  
            out.flush();  
            if (msg.equals("bye")) {  
                break;  
            }  
            System.out.println(in.readLine());  
        }  
        socket.close();  
    }  
}  

最后,首先运行MyServer类,然后MyClient类,然后在MyClient的控制台输入任意字符,可以看到当输入bye是server和client都会退出。

 

本文转自:http://blog.csdn.net/kongxx/article/details/7259436

 

 

 

//另一个简单例子:

WsPool:

package com.sm.common.socket;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.java_websocket.WebSocket;

public class WsPool {
    private static final Map<WebSocket, String> wsUserMap = new HashMap<WebSocket, String>();

    /**
     * 通过websocket连接获取其对应的用户
     */
    public static String getUserByWs(WebSocket conn) {
        return wsUserMap.get(conn);
    }

    /**
     * 根据userName获取WebSocket,这是一个list,此处取第一个
     * 因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了)
     */
    public static WebSocket getWsByUser(String userName) {
        Set<WebSocket> keySet = wsUserMap.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String cuser = wsUserMap.get(conn);
                if (cuser.equals(userName)) {
                    return conn;
                }
            }
        }
        return null;
    }

    /**
     * 向连接池中添加连接
     */
    public static void addUser(String userName, WebSocket conn) {
        wsUserMap.put(conn, userName); // 添加连接
    }

    /**
     * 获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组
     */
    public static Collection<String> getOnlineUser() {
        List<String> setUsers = new ArrayList<String>();
        Collection<String> setUser = wsUserMap.values();
        for (String u : setUser) {
            setUsers.add(u);
        }
        return setUsers;
    }

    /**
     * 移除连接池中的连接
     */
    public static boolean removeUser(WebSocket conn) {
        if (wsUserMap.containsKey(conn)) {
            wsUserMap.remove(conn); // 移除连接
            return true;
        } else {
            return false;
        }
    }

    /**
     * 向特定的用户发送数据
     */
    public static void sendMessageToUser(WebSocket conn, String message) {
        if (null != conn && null != wsUserMap.get(conn)) {
            conn.send(message);
        }
    }

    /**
     * 向所有用户名中包含某个特征得用户发送消息
     */
    public static void sendMessageToSpecialUser(String message, String special) {
        Set<WebSocket> keySet = wsUserMap.keySet();
        if (special == null) {
            special = "";
        }
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String user = wsUserMap.get(conn);
                try {
                    if (user != null) {
                        String[] cus = user.split("_");
                        if (cus[0] != null && !"".equals(cus[0])) {
                            String cusDot = "," + cus[0] + ",";
                            if (cusDot.contains("," + special + ",")) {
                                conn.send(message);
                            }
                        } else {
                            conn.send(message);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    // wsUserMap.remove(conn);
                }
            }

        }
    }

    /**
     * 向所有的用户发送消息
     */
    public static void sendMessageToAll(String message) {
        Set<WebSocket> keySet = wsUserMap.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String user = wsUserMap.get(conn);
                if (user != null) {
                    conn.send(message);
                }
            }
        }
    }

}

 

MyWebSocket:


package com.sm.common.socket;


import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;


import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;


import com.alibaba.fastjson.JSONObject;


public class MyWebSocket extends WebSocketServer {


public MyWebSocket() throws UnknownHostException {
super();
}


public MyWebSocket(int port) {
super(new InetSocketAddress(port));
}


public MyWebSocket(InetSocketAddress address) {
super(address);
}


@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
// ws连接的时候触发的代码,onOpen中我们不做任何操作
}


@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
// 断开连接时候触发代码
userLeave(conn);
System.out.println(reason);
}


@Override
public void onMessage(WebSocket conn, String message) {
// 有用户连接进来
Map<String, String> obj = (Map<String, String>) JSONObject.parse(message);
System.out.println(message);
String username = obj.get("name");
userJoin(conn, username);
}


@Override
public void onError(WebSocket conn, Exception ex) {
// 错误时候触发的代码
System.out.println("on error");
ex.printStackTrace();
}


/**
* 去除掉失效的websocket链接
*/
private void userLeave(WebSocket conn) {
WsPool.removeUser(conn);
}


/**
* 将websocket加入用户池
*
* @param conn
* @param userName
*/
private void userJoin(WebSocket conn, String userName) {
System.out.println("=============" + userName + "===============");
WsPool.addUser(userName, conn);
}
}

 

 

微信小程序端代码:

 onLoad: function (options) {
      //生成socket
      if (app.globalData.socketStatus === 'closed') {
        this.openSocket();
    }
}

 
  openSocket() {
    console.log("进入opensocket")
    var that = this;
    //打开时的动作
     wx.onSocketOpen(() => {
       console.log('WebSocket 已连接')
       app.globalData.socketStatus = 'connected';
       that.sendMessage();
     })
     //断开时的动作
     wx.onSocketClose(() => {
       console.log('WebSocket 已断开')
       app.globalData.socketStatus = 'closed'
     })
     //报错时的动作
     wx.onSocketError(error => {
       console.error('socket error:', error)
     })
     // 监听服务器推送的消息
     wx.onSocketMessage(message => {
       //把JSONStr转为JSON
       //message = message.data.replace(" ", "");
      //  if (typeof message != 'object') {
      //    message = message.replace(/\ufeff/g, ""); //重点
      //    var jj = JSON.parse(message);
      //    message = jj;
      //  }
       console.log("【websocket监听到消息】内容如下:");
       console.log(message);
       if(message.data==="1"||message.data==="2"||message.data==="3"){
       // 商品项目1 套餐卡2 会员卡 3
        wx.showToast({
          title: "代支付订单已支付成功",
        })
        that.closeSocket();
        
        that.onFavorSuccess(message.data);
       }
       
     })
     // 打开信道
     wx.connectSocket({
       url: app.globalData.socketAddr,
     })
   },
   //关闭信道
   closeSocket() {
    if (app.globalData.socketStatus === 'connected') {
      wx.closeSocket({
        success: () => {
          app.globalData.socketStatus = 'closed'
        }
      })
    }
  },
   //发送消息函数
   sendMessage() {
    if (app.globalData.socketStatus === 'connected') {
    //自定义的发给后台识别的参数 ,我这里发送的是name
    console.log()
      wx.sendSocketMessage({
        data: "{\"name\":\"" + wx.getStorageSync('userId') + "\"}"  
      })
    }
  },
 
//余额支付成功后跳转页面
  onFavorSuccess: function (type) {

    var that = this;
    //商品项目1 套餐卡2 会员卡 3
        //余额 购买成功  
        if (type === '2') {
          //跳转至套餐卡列表
        
          setTimeout(function () { 
            wx.redirectTo({
              url: '/pages/user/memberCard/memberCard',
            }) }, 1000);
        } else if (type === '3') {
          //跳转至会员卡列表
        
          setTimeout(function () { 
            wx.redirectTo({
              url: '/subpackages/pages/perCter/vipSeniorMember/vipSeniorMember',
            }) }, 1000);
        } else if (type == '1') {
         
          setTimeout(function () { 
            wx.redirectTo({
              url: '/pages/user/userOrder/userOrder?type=0',
            }) }, 1000);
    
        }
      }
 

 

posted @ 2017-07-05 10:35  陈扬天  阅读(325)  评论(0编辑  收藏  举报