java socket client-server-client小例子

首先定义一个Msg类 类中包含 发送者 接收者 及消息
public class Msg {
    private String sender;
    private String receiver;
    private String msg;

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public String getReceiver() {
        return receiver;
    }

    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

然后定义一个 全局Map 来存储在线人数

public class OnlineMap {
    private final static Map<String, Object> onlineMap = Maps.newHashMap();
    public static Object get(String key) {
        return onlineMap.get(key);
    }
    public static void put(String key, Object obj) {
        onlineMap.put(key, obj);
    }
    public static int getCount() {
        return onlineMap.size();
    }
    public static void remove(String key) {
        onlineMap.remove(key);
    }
    public static String getOnlineInfo() {
        Iterator iterator = onlineMap.keySet().iterator();
        StringBuilder builder = new StringBuilder();
        while (iterator.hasNext()) {
            builder.append(iterator.next()).append(",");
        }
        return builder.toString();
    }
}
接着定义 服务端

public class TalkServer {
    //用户集合
    private static ArrayList<Socket> list = new ArrayList<Socket>();

    public static void main(String[] args) {

        //上线用户
        Socket s = null;

        //用户
        String ip = null;
        String name = null;
        try {

            //构建服务器对象
            ServerSocket ss = new ServerSocket(1234);

            //构建 用户集合
            list = new ArrayList<Socket>();

            System.out.println("服务器准备就绪 ...");

            //循环监听
            while(true){

                //上线用户
                s = ss.accept();

                BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
                //上线的人都添加到 集合中
                list.add(s);
                name = reader.readLine();
                OnlineMap.put(name, s);
                System.out.println(OnlineMap.getOnlineInfo());
                //获取 Socket IP
                ip = s.getInetAddress().getHostAddress();
                System.err.println( ip + name +" 用户上线了 , 当前在线用户为: " + list.size() + "人 !"+OnlineMap.getOnlineInfo() );

                //构建 发送信息线程
                M2MSend send = new M2MSend(s, name);
                send.start();

            }

        } catch (IOException e) {
           e.printStackTrace();
        }

    }

    public static ArrayList<Socket> getList() {
        return list;
    }

    public static void setList(ArrayList<Socket> list) {
        TalkServer.list = list;
    }

}
服务端中包含一个 转发消息的 线程类M2MSend

public class M2MSend extends Thread{
    //用户集合
    private ArrayList<Socket> list = TalkServer.getList();
    //当前用户
    private Socket s;
    private String name;
    public M2MSend(Socket s, String name){
        this.s = s;
        this.name = name;
    }

    public void run(){

        //获取该用户 IP
        String ip = s.getInetAddress().getHostAddress();

        try {

            //读取用户信息
            BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            ObjectMapper mapper = JsonUtil.getMapper();
            //不断的读取写出数据
            while(true){

                //接收数据
                String info = null;

                //如果读取信息不为空
                if((info=reader.readLine()) != null){
                    Msg msg = mapper.readValue(info, Msg.class);
                    Socket ss = (Socket) OnlineMap.get(msg.getReceiver());
                    //遍历所有的在线用户,并且把信息发送过去
                    if (ss != null) {
                        PrintWriter pw = new PrintWriter(ss.getOutputStream());
//                        msg.setMsg(ip + " "+ msg.getSender() +" 说: " + msg.getMsg());
                        //写入信息
                        pw.println(mapper.writeValueAsString(msg));
                        pw.flush();
                    } else {
                        for(Socket sss : list){

                            //获取对象的输出流
                            PrintWriter pw;
                            pw = new PrintWriter(sss.getOutputStream());
//                            msg.setMsg(ip + " "+ msg.getSender() +" 说: " + msg.getMsg());
                            //写入信息
                            pw.println(mapper.writeValueAsString(msg));
                            pw.flush();

                        }
                    }

                }
            }

        } catch (IOException e1) {
            //用户下线
            list.remove(s);
            OnlineMap.remove(name);
            System.err.println(ip + name +" 已下线 , 当前在线人数为: " + list.size() + " 人 !"+OnlineMap.getOnlineInfo());
        }


    }
}
然后定义客户端

public class TalkClient {

    public static void main(String[] args) {

        try {

            //先从键盘接收信息
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

            System.out.println("请输入昵称:");
            String sender = br.readLine();
            //构建客户端对象
            Socket s = new Socket("localhost", 1234);
            //写入到 Socket 中
            PrintWriter pw = new PrintWriter(s.getOutputStream());
            pw.println(sender);
            pw.flush();
            ObjectMapper mapper = JsonUtil.getMapper();
            //启动线程
            M2MReceive receive = new M2MReceive(s);
            receive.start();
            while (true) {
                Msg msg = new Msg();
                System.out.println("请输入接收人:");
                String receiver = br.readLine();
                System.out.println("请输入发送的消息:");
                String message = br.readLine();
                msg.setSender(sender);
                msg.setReceiver(receiver);
                msg.setMsg(message);

                if (msg != null) {
                    System.out.println("自己说:" + message);
                    //写出
                    pw.println(mapper.writeValueAsString(msg));
                    pw.flush();
                }

            }


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
客户端中包含一个 接收服务端消息的线程类M2MReceive

public class M2MReceive extends Thread{
    private Socket s;

    public M2MReceive(Socket s){
        this.s = s;
    }

    public void run(){

        try {
            String ip = s.getInetAddress().getHostAddress();
            //构建输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            ObjectMapper mapper = JsonUtil.getMapper();
            //不断的接收信息
            while(true){

                String info = null;

                //接收信息
                if((info=br.readLine()) != null){
                    System.out.println(info);
                    Msg msg = mapper.readValue(info, Msg.class);
                    System.out.println(ip + " "+ msg.getSender() +" 说: " + msg.getMsg());
                    System.out.println("请输入接收人:");
                }

            }


        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}


运行说明 

首先 运行server main方法 客户端登陆后会显示登陆人数 及 登陆人昵称列表

其次运行 client main方法 然后 客户端 会让在控制台输入昵称 该昵称为客户端的标识 然后会询问你 要发送给哪个昵称  然后输入消息

就可以 在对应昵称的客户端中看到发送的消息了


该例子用到了 apache的 jackson  和 guava的 Maps  需下载引入 






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值