首页 > 编程语言 >Java网络编程实现一(服务器)对多(客户端)

Java网络编程实现一(服务器)对多(客户端)

时间:2023-11-02 22:23:26浏览次数:38  
标签:Java socket 编程 catch new socketList Socket 客户端

使用多线程+网络编程实现一个服务器对多个客户端

在该程序中用到的知识点

  1. java的BIO
  2. ServerSocket和Socket 网络编程
  3. 多线程的知识(个人认为重要)

实现的思路

服务器端(使用多个线程)

  1. 在客户端需要有一个集合来存储已经连接上的客户端, 如果客户端断开连接则需要从集合中删除
  2. 创建一个线程来处理客户端的连接
  3. 每一个客户端的连接都需要一个线程来接收客户端的请求
  4. 使用主线程来给客户端发送数据(轮询客户端集合中的Socket给客户端发送数据)

客户端(使用两个线程)

  1. 首先创建一个线程来接收服务器端的数据
  2. 使用主线程来给服务器端发送数据

 

服务器端:

  1 package 菜鸟教程.网络编程.多线程网络编程;
  2 
  3 import java.io.*;
  4 import java.net.ServerSocket;
  5 import java.net.Socket;
  6 import java.net.SocketException;
  7 import java.util.ArrayList;
  8 import java.util.List;
  9 import java.util.Scanner;
 10 
 11 public class Server {
 12 
 13     public static void main(String[] args) {
 14         List<Socket> socketList = new ArrayList<>();
 15 
 16         // 开启线程接收客户端的连接
 17         new Thread(new AcceptSocket(socketList)).start();
 18 
 19         while (true) {
 20             Scanner scanner = new Scanner(System.in);
 21             String sendInfo = scanner.nextLine();
 22             // 循环向所有的客户端发送消息
 23             socketList.forEach(socket -> {
 24                 try {
 25                     PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
 26                     printWriter.println(sendInfo);
 27                     printWriter.flush();
 28                 } catch (SocketException e) {
 29                     System.out.println(1);
 30                 } catch (IOException e) {
 31                     e.printStackTrace();
 32                 }
 33             });
 34         }
 35     }
 36 }
 37 
 38 // 接收客户端Socket线程
 39 class AcceptSocket implements Runnable {
 40 
 41     List<Socket> socketList;
 42 
 43     public AcceptSocket(List<Socket> socketList) {
 44         this.socketList = socketList;
 45     }
 46 
 47     @Override
 48     public void run() {
 49         ServerSocket serverSocket = null;
 50         try {
 51             serverSocket = new ServerSocket(9000);
 52             System.out.println("监听客户端的连接");
 53             // 循环接收客户端的请求
 54             while (true) {
 55                 Socket socket = serverSocket.accept();
 56                 // 接收到后加入到 socketList
 57                 socketList.add(socket);
 58                 // 开启处理客户端线程
 59                 new Thread(new HandleSocket(socket, socketList)).start();
 60             }
 61         } catch (SocketException e) {
 62             System.out.println(2);
 63         } catch (IOException e) {
 64             e.printStackTrace();
 65         } finally {
 66             // 关闭连接
 67             try {
 68                 if (null != serverSocket) {
 69                     serverSocket.close();
 70                 }
 71             } catch (IOException e) {
 72                 e.printStackTrace();
 73             }
 74 
 75         }
 76     }
 77 }
 78 
 79 // 处理客户端Socket线程
 80 class HandleSocket implements Runnable {
 81 
 82     Socket socket;
 83 
 84     List<Socket> socketList;
 85 
 86     public HandleSocket(Socket socket, List<Socket> socketList) {
 87         this.socket = socket;
 88         this.socketList = socketList;
 89     }
 90 
 91     @Override
 92     public void run() {
 93         BufferedReader bufferedReader = null;
 94         try {
 95             // 读取客户端发来的数据
 96             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 97             System.out.println("等待读取客户端:" + socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + " 的消息");
 98             while (true) {
 99                 String clientInfo = bufferedReader.readLine();
100                 System.out.println(socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + "发送的消息是:" + clientInfo);
101             }
102         } catch (SocketException e) {
103             // 强制关闭连接后的处理
104             System.out.println(socket.getLocalAddress().toString().substring(1) + ":" + socket.getPort() + "断开连接");
105             // 将该连接从socketList中移除
106             socketList.remove(socket);
107         } catch (IOException e) {
108             e.printStackTrace();
109         } finally {
110 
111             // 关闭连接
112             try {
113                 if (null != bufferedReader) {
114                     bufferedReader.close();
115                 }
116                 if (null != socket) {
117                     bufferedReader.close();
118                 }
119             } catch (IOException e) {
120                 e.printStackTrace();
121             }
122 
123         }
124     }
125 }

 

客户端

 1 package 菜鸟教程.网络编程.多线程网络编程;
 2 
 3 import java.io.*;
 4 import java.net.Socket;
 5 import java.net.SocketException;
 6 import java.util.Scanner;
 7 
 8 public class Client {
 9     public static void main(String[] args) {
10         Scanner scanner = new Scanner(System.in);
11         Socket socket = null;
12         PrintWriter printWriter = null;
13         try {
14             socket = new Socket("localhost", 9000);
15             printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
16 
17             //开启线程接收服务端的消息
18             new Thread(new AcceptServer(socket)).start();
19             System.out.println("可以给服务器端发送数据了");
20             while (true) {
21                 // 给服务端发送消息
22                 String sendInfo = scanner.nextLine();
23                 printWriter.println(sendInfo);
24                 printWriter.flush();
25             }
26 
27         } catch (IOException e) {
28             e.printStackTrace();
29         } finally {
30             // 关闭连接
31             try {
32                 if (null != socket) {
33                     socket.close();
34                 }
35                 if (null != printWriter) {
36                     printWriter.close();
37                 }
38             } catch (IOException e) {
39                 e.printStackTrace();
40             }
41 
42         }
43     }
44 }
45 
46 class AcceptServer implements Runnable {
47 
48     Socket socket;
49 
50     public AcceptServer(Socket socket) {
51         this.socket = socket;
52     }
53 
54     @Override
55     public void run() {
56         BufferedReader bufferedReader = null;
57         try {
58             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
59             while (true) {
60                 String serverInfo = bufferedReader.readLine();
61                 System.out.println("服务器的消息为:" + serverInfo);
62             }
63         } catch (SocketException e) {
64             System.out.println("服务器异常关闭");
65             // 退出
66             System.exit(0);
67         } catch (IOException e) {
68             e.printStackTrace();
69         } finally {
70             // 关闭连接
71             try {
72                 if (null != bufferedReader) {
73                     bufferedReader.close();
74                 }
75                 if (null != socket) {
76                     socket.close();
77                 }
78             } catch (IOException e) {
79                 e.printStackTrace();
80             }
81         }
82     }
83 }

 

 

 

 

标签:Java,socket,编程,catch,new,socketList,Socket,客户端
From: https://www.cnblogs.com/szmtjs10/p/17806477.html

相关文章

  • JUC并发编程学习笔记(四)8锁现象
    8锁现象八锁->就是关于锁的八个问题锁是什么,如何判断锁的是谁对象、class模板深刻理解锁锁的东西无外乎就两样:1、同步方法的调用者,2、Class模板。同一个锁中,只有当前线程资源释放后才会被下一个线程所接手。同步方法的调用者是两个不同的实例时,互不相关。静态同步方法(s......
  • java
    我们先剖析一个完整的Java程序,它的基本结构是什么:/***可以用来自动创建文档的注释*/publicclassHello{publicstaticvoidmain(String[]args){//向屏幕输出文本:System.out.println("Hello,world!");/*多行注释开始注释......
  • java 网络编程之传输文件
    需要建两个类,分别作为服务器(接收文件)和客户端(发送文件) 1.服务器类:1package菜鸟教程.网络编程.网络编程之传输文件;23importjava.io.*;4importjava.net.InetAddress;5importjava.net.ServerSocket;6importjava.net.Socket;78/**9*服......
  • java网络编程与多线程
      一、Java 网络编程网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。java.net包中提供了两种常见的网络......
  • 在JavaScript中移除字符串中的重音符号/变音符号
    内容来自DOChttps://q.houxu6.top/?s=在JavaScript中移除字符串中的重音符号/变音符号如何从字符串中移除重音符号?特别是在IE6中,我曾经使用过以下代码:accentsTidy=function(s){varr=s.toLowerCase();r=r.replace(newRegExp(/\s/g),"");r=r.replace(......
  • Java NIO包结构简介
    layout:postread_time:trueshow_date:truetitle:JavaNIO包结构date:2023-07-0910:12:10-0600description:JavaNIO包结构简述.img:posts/java-nio/cover.pngtags:[java,IO,JavaNIO,ChannelIO,Buffer,threadsafty,multiplexer,charset]author:尹......
  • Java_消息队列
    消息系统MQ全称MessageQueue(消息队列)消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等,而部分数据库如Redis、MySQL以及phxsql也可实现消息队列的功能系统管理者MessageManager包括Apache的ActiveMQ,Apache的Kafka,RabbitMQ、memcacheQ消息类型......
  • 前端基础之JavaScript
    前端基础之JavaScriptJavaScript概述ECMAScript和JavaScript的关系1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这门语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称......
  • JavaScript基础
    引入方式JavaScript程序不能独立运行,它需要被嵌入HTML中,然后浏览器才能执行JavaScript代码。内部引入写在body结束标签的上方。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content=&......
  • JUC并发编程学习笔记(三)生产者和消费者问题
    生产者和消费者问题synchronized版->wait/notifyjuc版->Lock面试:单例模式、排序算法、生产者和消费者、死锁生产者和消费者问题Synchronized版packageorg.example.pc;publicclassA{publicstaticvoidmain(String[]args){Datedate=newDate();......