java socket 线程池_程序员:java使用线程池和TCP实现简单多轮聊天系统

最近在做物联网项目,需要使用TCP和传感器进行双向交互,通过这种渠道,找到了下面的代码,写成博客主要也是为了记录一下,以后用到随时可以看。

代码实现

服务端

package com.tcp;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.io.ObjectInputStream.GetField;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class TalkServer {

public static int i = 0;

private static final int PORT = 9620; // 端口号

private static List user_list = new ArrayList(); // 保存连接对象

private ExecutorService exec;//线程池

private ServerSocket server;//用来监听端口

public static void main(String[] args) {

// 启动服务器程序

new TalkServer();

}

public TalkServer() {

try {

server = new ServerSocket(PORT);

// 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们

exec = Executors.newCachedThreadPool();

System.out.println("服务器已启动!");

Socket client = null;

while (true) {

client = server.accept(); // 接收客户连接

user_list.add(client);// 将用户添加进列表

System.out.println("端口号为: " + user_list.get(i).getPort());// 输出用户端口号

i++;// 列表下标加一

exec.execute(new s_talk(client));//运行s_talk方法

}

} catch (IOException e) {

e.printStackTrace();

}

}

static class s_talk implements Runnable {

private Socket socket;

private InputStream is = null;//输入流

private OutputStream os = null;//输出流

private String msg;

public s_talk(Socket socket) throws IOException {

this.socket = socket;

is = this.socket.getInputStream();

msg = "【" + this.socket.getPort() + "】进入聊天室!当前聊天室有【"+ user_list.size() + "】人"+"(";

for(Socket st:user_list){

msg+=st.getPort()+",";

}

msg+=")";

System.out.println(msg);

for (Socket client : user_list) {

os = client.getOutputStream();

os.write(msg.getBytes());//把在线人数信息输出到每个客户端

}

}

public void run() {

try {

int len;

byte[] b = new byte[1024];//字节

while ((len = is.read(b)) != -1) {

msg = new String(b, 0, len);//将数据存储到msg

//私聊判定

if (msg.indexOf("@") != -1) {

int n = 0;

String stt = null;

for (n = 0; n < user_list.size() - 1; n++) {

stt = "" + user_list.get(n).getPort();//将端口号转换为字符串类型

if (msg.indexOf(stt) != -1) {

break;//没找到此端口号,跳出循环

}

}

String Str = null;

int duan = socket.getPort();

String st = "" + duan;

int num1 = st.length();//端口号长度

int num = msg.length();

Str = msg.substring(num1 + 1, num);

os = user_list.get(n).getOutputStream();//将信息存入输出流

os.write((socket.getPort() + "对我说:" + Str).getBytes());//打印出私聊信息

//System.out.println("私聊接收端口"+user_list.get(n).getPort());//在服务器显示私聊端口号及其数据

System.out.println(socket.getPort() +"对"+user_list.get(n).getPort()+ "发送的私聊消息:"+ "发送的数据-------" + Str);

} else

{

//判定退出,trim()用于去掉开头和结尾的空格

if (msg.trim().equals("bye")) {

user_list.remove(socket);// 删除一个元素

is.close();//关闭输入输出流

os.close();

msg = "【" + socket.getPort()+ "】离开聊天室!当前聊天室有【" + user_list.size()+ "】人";

socket.close();

System.out.println(msg);

for (Socket client : user_list) {

os = client.getOutputStream();

os.write(msg.getBytes());

}

break;

} else

{ //群聊

msg = "【" + socket.getPort() + "】说:" + msg;

System.out.println(msg);

for (Socket client : user_list) {

os = client.getOutputStream();

os.write(msg.getBytes());

}

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

客户端

package com.tcp;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.PrintStream;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;

import java.util.Scanner;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class TalkClient {

public static String ip = "127.0.0.1";

private static final int PORT = 9620;

private static ExecutorService exec = Executors.newCachedThreadPool(); // 线程池

public static void main(String[] args) throws Exception {

// 启动客户端函数

new TalkClient();

}

public TalkClient() {

try {

Socket socket = new Socket(ip, PORT); // 连接端口

exec.execute(new c_send(socket));// 启动客户端线程

System.out.println("【" + socket.getLocalAddress() + "】您好,欢迎来到神华客户端!");

InputStream is = null;

is = socket.getInputStream();// 创建输入流

String msg;

int len;

byte[] b = new byte[1024];

while ((len = is.read(b)) != -1) {

msg = new String(b, 0, len);// 将消息存入字节数组并赋给msg

System.out.println(msg);

}

} catch (Exception e) {

e.printStackTrace();

}

}

class c_send implements Runnable {

private Socket socket;// 定义套接字

public c_send(Socket socket) {

this.socket = socket;

}

public void run() {

try {

InputStream is = null;

is = socket.getInputStream();// 获取输入输出流

OutputStream os = null;

os = socket.getOutputStream();

String msg;

while (true) {

String stt = null;

Scanner sc = new Scanner(System.in);// 输入欲发送的信息

msg = sc.next();// 把值返回给msg并打印

os.write(msg.getBytes());

if (msg.trim().equals("bye")) {

is.close();

os.close();

exec.shutdownNow();//关闭线程池

break;

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

实现效果

客户端

68f356ce86badcd81857c26eb207984c.png

服务端

a07e907bbf6da4ce48baa9311a82522d.png

以上代码经过本地测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云李飞飞:中国数据库的时与势

简介&#xff1a;数据库、操作系统和中间件并列为三大基础软件&#xff0c;无论是在银行存取款&#xff0c;还是进行健康码查询&#xff0c;我们的日常应用和企业业务背后都离不开数据库。可以说&#xff0c;没有数据库&#xff0c;就难以构建数字化底座。过去的40多年&#xf…

阿里巴巴超大规模 Kubernetes 基础设施运维体系介绍

简介&#xff1a;ASI 作为阿里集团、阿里云基础设施底座&#xff0c;为越来越多的云产品提供更多专业服务&#xff0c;托管底层 K8s 集群&#xff0c;屏蔽复杂的 K8s 门槛、透明几乎所有的基础设施复杂度&#xff0c;并用专业的产品技术能力兜底稳定性&#xff0c;让云产品只需…

数据库资深“学霸”再启程,专访数据库初创公司矩阵起源全球 CTO 田丰博士

师出名门&#xff0c;工业界履历从大厂首席工程师到创业公司 CTO&#xff0c;并能一直从事底层系统的核心研发工作&#xff0c;可能是很多优秀技术人向往的光鲜履历。不过抛弃大厂的光鲜稳定工作和成功的创业项目&#xff0c;再次加入初创公司&#xff0c;则需要比常人更大的魄…

Spring官方RSocket Broker 0.3.0发布: 快速构建你的RSocket架构

简介&#xff1a;Spring官方的RSocket Broker其实开发已经非常久了&#xff0c;我以为会伴随着Spring Cloud 2021.0发布的&#xff0c;但是没有发生。不过Spring RSocket Broker还是发布了最新的0.3版本&#xff0c;虽然还是预览版&#xff0c;但目前已经可用&#xff0c;考虑官…

Redis 6 中的多线程是如何实现的!?

作者 | 张彦飞allen来源 | 开发内功修炼Redis 是一个高性能服务端的典范。它通过多路复用 epoll 来管理海量的用户连接&#xff0c;只使用一个线程来通过事件循环来处理所有用户请求&#xff0c;就可以达到每秒数万 QPS 的处理能力。下图是单线程版本 Redis 工作的核心原理图单…

如何构建流量无损的在线应用架构 | 专题开篇

简介&#xff1a;本篇是整个《如何构建流量无损的在线应用架构》系列的第一篇&#xff0c;这一系列共三篇&#xff0c;旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类&#xff0c;这些问题的解决方案有的只是一些代码层面的细节&#xff0c;有的需要工具…

云原生时代的运维体系进化

简介&#xff1a;基于容器、Kubernetes 等云原生技术&#xff0c;提供的开放社区标准、不可变基础设施、声明式 API 会成为企业 CloudOps 的最佳实践&#xff0c;也将在这个基础上推进数据化、智能化体系建设&#xff0c;将运维复杂性进一步下沉&#xff0c;让企业可以聚焦于自…

企业如何从 0 到 1 构建整套全链路追踪体系

简介&#xff1a;本文将分享 ARMS 在全链路追踪领域的最佳实践&#xff0c;分享主要分为四部分。首先&#xff0c;是对分布式链路追踪的整体简介。其次&#xff0c;是对 ARMS 在分布式链路追踪领域的核心能力进行介绍。然后&#xff0c;介绍如何从 0 到 1 构建整套全链路追踪体…

React18 的 useEffect 新特性为什么被疯狂吐槽?

作者 | 零一来源 | 前端印象react18 已经出来一段时间了&#xff0c;create-react-app 默认安装的 React 版本也已经是 18&#xff0c;不知道有没有小伙伴发现自己有点看不懂 React 了&#xff1f;import { useEffect, useState } from reactfunction App () {const [data, set…

如何构建一个流量无损的在线应用架构 | 专题中篇

简介&#xff1a;本篇是整个《如何流量无损的在线应用架构》系列的第二篇&#xff0c;这一系列共三篇&#xff0c;旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类&#xff0c;这些问题的解决方案有的只是一些代码层面的细节&#xff0c;有的需要工具进行…

一文读懂蓝绿发布、A/B 测试和金丝雀发布的优缺点

简介&#xff1a;目前&#xff0c;业界已经总结出了几种常见的服务发布策略来解决版本升级过程中带来的流量有损问题。本文首先会对这些普遍的发布策略进行简单的原理解析&#xff0c;最后结合阿里云的云原生网关对这些发布策略进行实践。 作者 | 扬少 背景 目前&#xff0c…

Kafka 到底有多高可靠?

作者 | 敖丙来源 | 敖丙什么叫可靠性&#xff1f;大家都知道&#xff0c;系统架构有三高&#xff1a;「高性能、高并发和高可用」&#xff0c;三者的重要性不言而喻。对于任意系统&#xff0c;想要同时满足三高都是一件非常困难的事情&#xff0c;大型业务系统或者传统中间件都…

阿里云张振尧:阿里云边缘云驱动5G时代行业新价值

简介&#xff1a;近日&#xff0c;以“5G融合通信趋势下的技术创新”为主题的2021中国增值电信及虚拟运营高峰论坛在北京召开&#xff0c;阿里云边缘云高级产品专家张振尧发表了《阿里云边缘云驱动5G时代行业新价值》主题演讲&#xff0c;分享了阿里云边缘云作为5G时代的新基础…

美的工业技术亮相2022汉诺威工业博览会,助力全球工业向数字化与可持续迈进

2022年5月31日&#xff0c;2022汉诺威工业博览会开幕并重启线下展览&#xff0c;美的工业技术以“科技驱动&#xff0c;拥抱高效、绿色、智能的工业未来”为主题&#xff0c;携旗下工业自动化品牌“高创”、 “合康新能”和“东菱”&#xff0c;以覆盖自动化、绿色能源领域的领…

hyengine - 面向移动端的高性能通用编译/解释引擎

简介&#xff1a;手机淘宝客户端在历史上接过多种多样的脚本引擎&#xff0c;用于支持的语言包括&#xff1a;js/python/wasm/lua&#xff0c;其中js引擎接过的就有&#xff1a;javascriptcore/duktape/v8/quickjs 等多个。众多的引擎会面临共同面临包大小及性能相关的问题&…

如何进行基于Anolis OS的企业级Java应用规模化实践?|龙蜥技术

简介&#xff1a;提供了724小时的专属钉钉或者电话支持&#xff0c;响应时间保证到在业务不可用情况下10分钟响应&#xff0c;业务一般的问题在一小时可以获得响应&#xff0c;主要城市可以两小时内得到到达现场的服务。 本文作者郁磊&#xff0c;是Java语言与虚拟机SIG负责人…

大数据的下一站 DataOps,智领云发布纯 K8s 云原生数据平台 BDOS Online

最近几年&#xff0c;业界对数据中台的追捧度像坐过山车从高点走低&#xff0c;但在数字化和业务创新驱动下&#xff0c;对数据管理与分析的热度在今年不降反升。 以往搭建一套 Hadoop 大数据平台&#xff0c;技术团队重点要搞定数据的采集、存储、处理和数仓的设计搭建等复杂动…

“全”事件触发:阿里云函数计算与事件总线产品完成全面深度集成

简介&#xff1a;目前&#xff0c;函数计算已具备接入EventBridge所有事件源的触发能力&#xff0c;实现触达阿里云全系产品服务的“最后一公里”。 作者&#xff1a;史明伟&#xff08;世如&#xff09;阿里云高级技术专家 随着云原生技术的普及和落地&#xff0c;企业在构建…

开源 Serverless 里程碑:Knative 1.0 来了

简介&#xff1a;近期Knative发布了1.0版本&#xff0c;达到了一个重要的里程碑。Knative自2018年7月首次发布以来, 版本不断的迭代发展&#xff0c;除了无数的错误修复、稳定性和性能增强之外&#xff0c;按时间顺序还进行了一些改进&#xff0c;下文将进行简单介绍。 作者&a…

勒索软件攻击层出不穷,企业如何做好数据保护?

近日&#xff0c;“搜狐员工遭遇工资补助诈骗”事件引起广泛热议&#xff1a;搜狐员工收到一封来自“搜狐财务部”名为《5月份员工工资补助通知》的邮件&#xff0c;员工按照邮件要求扫码&#xff0c;填写银行账号等信息后&#xff0c;大家并没有等到“补助”&#xff0c;并且工…