两个客户端通信的socket简单实现
来源:互联网 发布:百度云资源淘宝暗语 编辑:程序博客网 时间:2024/06/11 02:02
两个客户端通信的socket简单实现
这段时间学习了socket,根据简单的服务器与客户端通信,做了一个两个客户端通过服务器来进行通信的小程序。
首先定义一个简单的消息类Message,该类只有两个属性,一个是接收消息的客户端的编号,一个是消息内容,代码如下::
import java.io.Serializable;public class Message implements Serializable { // 客户端编号 int id; // 消息内容 String msg; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; }}
接下来先创建服务器端,SocketNotifyServer类,该类创建了serverSocket对象,绑定本地的8888端口,声明静态变量sessionMap来保存所有已连接的客户端,并给每个客户端分配一个编号:
import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.HashMap;import java.util.Map;public class SocketNotifyServer { // socket服务 ServerSocket serverSocket = null; // 用来存放已连接的客户端的socket会话 static Map<Integer, Socket> sessionMap = new HashMap<Integer, Socket>(); public void socket() { try { // 创建serverSocket,绑定端口为8888 serverSocket = new ServerSocket(8888); System.out.println("服务器开启。。。"); // 客户端编号 int i = 1; // 实现多个客户端连接 while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端" + i + "连接成功。。。"); if (socket != null) { // 将socket放入map,key为客户端编号 sessionMap.put(i, socket); // 开启线程处理本次会话 Thread thread = new Thread(new NotifyHandler(socket, sessionMap)); thread.setDaemon(true); thread.start(); i++; } } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { new SocketNotifyServer().socket(); }}
接下来是消息处理类,通过重写的构造方法,得到消息发送方以及所有的已连接客户端。
通过ObjectInputStream和ObjectOutputStream来对message对象进行读写:
import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.net.Socket;import java.util.Map;public class NotifyHandler extends Thread { Socket socket = null; InputStream in = null; Map<Integer, Socket> sessionMap = null; public NotifyHandler(Socket socket, Map<Integer, Socket> sessionMap) { this.socket = socket; this.sessionMap = sessionMap; } public void run() { try { in = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(in); // 实现一次连接多次通话 while (true) { try { Message msg = (Message) ois.readObject(); System.out.println("消息接受对象:客户端" + msg.getId() + ",消息内容:" + msg.getMsg()); // 发送数据 try { Socket targetSocket = sessionMap.get(msg.getId()); OutputStream out = targetSocket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(msg); System.out.println("服务端已转发"); } catch (IOException e) { e.printStackTrace(); } if (socket.isClosed()) { break; } } catch (IOException e) { e.printStackTrace(); try { socket.close(); break; } catch (IOException e1) { e1.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } }}
最后是客户端的代码,由于没有界面以及其他原因,在客户端这里直接是默认[客户端1]和[客户端2]进行通信,所以代码中message对象的id属性是写死的,当[客户端1]启动的时候id属性的值为2,当[客户端2]启动时,id属性为1。此处把消息接收代码放在前面,是因为while (true){input = new InputStreamReader(System.in);
这里在阻塞着等待输入,如果接收消息的代码放在这段代码下方,会导致在没有发过消息的时候,接收消息的线程不会启动,收不到别的客户端发来的消息:
import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.net.Socket;public class MsgSocketClient { Socket socket = null; InputStreamReader input = null; InputStream in = null; OutputStream out = null; /** * @param args */ public void socketStart() { try { socket = new Socket("127.0.0.1", 8888); System.out.println("客户端1启动......."); // 接受返回数据 new Thread() { public void run() { try { while (true) { in = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(in); Message msg = (Message) ois.readObject(); System.out.println("返回数据:" + msg.getMsg()); } } catch (Exception e) { e.printStackTrace(); } } }.start(); out = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); while (true) { input = new InputStreamReader(System.in); String msg = new BufferedReader(input).readLine(); Message message = new Message(); message.setId(2); message.setMsg(msg); oos.writeObject(message); System.out.println("已发送"); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流和连接 try { in.close(); out.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { new MsgSocketClient().socketStart(); }}
运行结果如下图:
注意: in = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(in);
这里不能直接写成 ObjectInputStream ois = (ObjectInputStream)socket.getInputStream();
直接强转会报异常。
- 两个客户端通信的socket简单实现
- C++ 简单的 Tcp 实现[socket] 客户端与客户端通信
- C++ 简单的 Tcp 实现[socket] 客户端与客户端通信
- C++ 简单的 Tcp 实现[socket] 客户端与客户端通信
- C++ 简单的 Tcp 实现[socket] 服务器端与客户端通信
- Socket TCP 协议实现服务端和客户端的简单通信
- nodejs socket实现的服务端和客户端简单通信
- Socket通信,简单的用两个手机实现TCPIP
- 简单的Socket通信客户端和服务端
- socket通信的简单实现
- 实现服务器端和客户端的Socket通信
- Java Socket简单实现客户端与服务端通信
- Socket通信简单实现客户端-服务器消息发送
- socket编程(一),实现服务器与客户端简单通信
- 利用Tcp和socket实现的客户端与服务端的简单通信
- Java中利用socket实现简单的服务端与客户端的通信(入门级)
- Java中利用socket实现简单的服务端与客户端的通信(基础级)
- 网络编程:使用Socket实现简单的服务器和客户端的通信
- Java动态代理之实践
- Android Monkey测试入门-3-Monkey给指定app打压
- 【机器学习实战】制作五子棋AI之二:界面组合与棋子放置(pygame)
- 日本穷游攻略(1、 准备篇)
- Cookie与Session
- 两个客户端通信的socket简单实现
- laravel框架总结一
- .NET面试题
- 【VUE】vue分页插件share
- 简单的右侧缩略栏风铃效果
- Python之List、Set、Tuple、Dictionary的区别
- Softmax回归原理简介+代码详解
- HDU 5126 stars KDTree
- struts2常量配置详解以及简单理解流程