网络通信之server/client通信的实现
程序员文章站
2022-06-11 09:46:20
...
网络通信之server/client通信的实现
要求:实现服务器客户端通信,当服务器启动后一旦有客户端连接上服务器,服务器便给连接上的客户端发送”欢迎光临!“。每增加一个客户端,服务器都将客户端放入arraylist中,并显示在线客户端数。而客户端向服务器发送消息时,服务器会接收客户端发来的消息并将消息转发给所以在线的客户端。客户端和服务器端都有自己的发送和接收数据的线程。
服务端要求实现的功能:
1.每连上一个客户端,就主动给客户端发送一句“欢迎光临!”。
2.使用ArrayList存放连上服务端的所有客户端。
3.当接收到客户端发送来的消息的时候,将这条消息转发给所有连上服务端的所有客户端。
思路:
1.创建一个服务器套接字(ServerSocket),绑定到指定端口。
2.调用accept方法,侦听来自客户端的请求,如果客户发出请求,则接受连接,返回通信套接字(Socket)。
3.创建线程来处理客户机:发送和接收消息。
服务端:
//服务器端 public class MyServer { //使用ArrayList存放连上服务端的所有客户端 public static ArrayList<Socket> sockets = new ArrayList<Socket>(); public static void main(String[] args) { try { //创建一个服务器套接字,绑定到54321端口 ServerSocket server = new ServerSocket(54321); System.out.println("服务器已启动,正在等待连接"); while (true) { //调用accept方法,侦听来自客户端的请求 Socket socket = server.accept(); //将客户端发送过来的通信套接字添加到sockets动态数组中 sockets.add(socket); //输出在线的客户端个数 System.out.println("有" + sockets.size() + "个客户连接上"); //启动发送线程,给客户端发送一句“欢迎光临!” new getOutputStream(socket).start(); //启动接收线程,读取从客户端发来的消息 new getInputStream(socket).start(); } } catch (IOException e) { e.printStackTrace(); } } }
服务端负责发送欢迎光临的线程类:
//发送线程负责给客户端发送一句“欢迎光临!” class getOutputStream extends Thread{ private Socket s; public getOutputStream(Socket s) { this.s=s; } @Override public void run() { try { //获取输出流 OutputStream ops= s.getOutputStream(); String msg="欢迎光临!\n"; //将msg写入流 ops.write(msg.getBytes()); //刷新流 ops.flush(); } catch (IOException e) { e.printStackTrace(); } } }
服务器端从客户端接收数据的线程类:
//接收线程,读取从客户端发来的消息 class getInputStream extends Thread { private Socket r; public getInputStream(Socket r) { this.r = r; } public void run() { try { //获取输入流 InputStreamReader is = new InputStreamReader(r.getInputStream()); BufferedReader br = new BufferedReader(is); while (true) { //读取客户端发送过来的消息 String msg = br.readLine(); System.out.println("客户端发来" + msg); //读取客户端发送过来的消息后转发给所有在线的客户端 for (Socket socket : MyServer.sockets) { OutputStreamWriter osw = new OutputStreamWriter( socket.getOutputStream()); BufferedWriter bw = new BufferedWriter(osw); bw.write(msg + "\n"); //刷新流 bw.flush(); } } } catch (Exception e) { e.printStackTrace(); } } }
客户端
功能:
1.在命令行给服务端发送消息
2.当接收到服务端发来的消息的时候,将内容显示在控制台上
思路:
1.创建一个套接字(Socket) ,向服务器的侦听端口发出请求
2.与服务器正确连接后,获得输入/输出流,启动线程开始网络数据的接收和发送
客户端:
//客户端 public class MyClient { public static void main(String[] args) { try { //创建一个套接字(Socket) ,向服务器的侦听端口发出请求 Socket socket = new Socket("localhost", 54321); //启动读取数据线程,接收服务器发送过来的消息 new Cread(socket).start(); //启动发送数据线程,给服务器发送消息 new Csend(socket).start(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
客户端接收数据的线程类:
//读取数据线程,接收服务器发送过来的消息 class Cread extends Thread { private Socket r; public Cread(Socket r) { this.r = r; } public void run() { try { while (true) { //获取输入流 InputStreamReader is = new InputStreamReader(r.getInputStream()); BufferedReader br = new BufferedReader(is); //按行读取从服务器发来的数据消息 String content = br.readLine(); System.out.println("服务端发来" + content); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
客户端发送数据线程类:
//发送数据线程,给服务器发送消息 class Csend extends Thread { private Socket c; public Csend(Socket c) { this.c = c; } public void run() { try { //获取输出流 OutputStreamWriter osw = new OutputStreamWriter(c.getOutputStream()); BufferedWriter bw = new BufferedWriter(osw); //从键盘写入数据 Scanner sc = new Scanner(System.in); while (true) { //将键盘写入的数据按行写入发送给服务器 String msg = sc.nextLine() + "\n"; bw.write(msg); System.out.println("给服务器发送" + msg); //刷新流 bw.flush(); } } catch (IOException e) { e.printStackTrace(); } } }
上一篇: ssh整合时出现的问题
推荐阅读
-
Vue 之孙组件向爷组件通信的实现
-
Java虚拟机JVM之server模式与client模式的区别
-
Vue 之孙组件向爷组件通信的实现
-
python实现的udp协议Server和Client代码实例
-
libevent 实现的socket 通信 server以及解决找不到动态库的方法
-
Linux 进程通信之FIFO的实现
-
使用C#实现基于TCP和UDP协议的网络通信程序的基本示例
-
深入理解Golang之http server的实现
-
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
-
主机(client)与ubuntu虚拟机(server)的通信(Version 1.0)