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();
}
}
}
}
实现效果
客户端
服务端
以上代码经过本地测试。
java socket 线程池_程序员:java使用线程池和TCP实现简单多轮聊天系统相关推荐
- java post请求 json_好程序员Java教程分享Vue插件之Axios
好程序员Java教程分享Vue插件之Axios 环境安装: npm install --save axios vue-axios //安装axios Npm install //安装依赖 在main. ...
- java压测请求线程数_程序员撕开京东 618 大促压测的另一面 | 原力计划
作者 | 天涯泪小武 责编 | 王晓曼 出品 | CSDN博客 前天618大促演练进行了全链路压测,在此之前刚好我的热key探测框架也已经上线灰度一周了,小范围上线了几千台服务器,每秒大概接收几千个k ...
- java excel 插件开发工具_程序员常用的15 种开发者工具推荐
程序员常用的15 种开发者工具推荐:Java 线上诊断工具 Arthas.IDE 插件 Cloud Toolkit.混沌实验注入工具 ChaosBlade.Java 代码规约扫描插件.应用实时监控工具 ...
- java斗图表情_程序员之间的斗图表情包, java真的输惨了!
表情包成了人与人聊天中不可少的分量,陌生人聊天表情包丢出去妥妥的拉近关系变熟络啊(¬_¬) 而且可以用表情包化解尴尬.缓解气氛,可以没话找话.忙的时候也可以当做结束语,显得比较有礼貌! 对于沉默寡言. ...
- java数据库的量级_程序员学Python还是Java?分析了8张图后得出这个结论
Java和Python两门语言都是目前非常热门的语言,可谓北乔峰南慕容,二者不分上下,棋逢对手.但是对于初学者来说,非常困惑,因为时间和精力有限,上手必须要先学一门,到底选那个好呢,今天3分钟带你透彻 ...
- java装逼的话_程序员装逼指南(语言篇)
原标题:程序员装逼指南(语言篇) 语言:千万不要说自己是做Java或者.Net的,一下子就屌丝了.PHP现在也不行,Python稍微有点烂大街,但还是明显要强过前几个.剩下的可以说自己是做Ruby的, ...
- java异步队对联_程序员的春节对联集锦
上联:为系统而生,为框架而死,为debug奋斗一辈子! 下联:吃符号的亏,上大小写的当,最后死在需求上! 横批:杯具程序员. 上联:算法数据思路清晰 下联:编译链接一气呵成 横批:码到功成 上联:思前 ...
- java占位符填充_程序员:深入理解Java虚拟机,对象的内存布局
在 HotSpot 虚拟机中,对象在内存中存储的布局分为 3 块区域:对象头 ( Header ) .实例数据 ( InstanceData ) 和对齐填充 (Padding) . 一.对象的内存布局 ...
- java 证书查看工具_程序员必备工具 Java证书工具Keytool的使用
一.简介 Keytool是JDK自带的证书管理工具,在jdk/bin目录下,可以用来生成自签名证书.导入导出证书.打印证书信息等. 回顾下前一章的一些概念:PKI:公钥基础设施 X.509 : PKI ...
最新文章
- TCC分布式事务的实现原理
- [译] Robinhood 为什么使用 Airflow
- angularjs与java_关于angularjs与java结合,获取后台数据并解析的问题
- Shell 显示带颜色字体
- linux写聊天程序,轻易实现基于linux或win运行的聊天服务端程序
- SAP Spartacus里,点击checkbox右边的span文本,不会触发checkbox勾选的原因
- python怎么输出结果_Python中print()常用输出方法
- 将XML解析成DOM文档
- 准备入行Web前端,又担心适不适合,怎么办?
- [C] 库函数 sprintf() 和 snprintf()
- 服务器cpu哪个型号超频,服务器CPU也超频,AMD霄龙性能暴涨1.5倍-控制器/处理器-与非网...
- “ +”(加号)CSS选择器是什么意思?
- shell编写三角函数_VB中三角函数计算.doc
- 零基础学VB6.0仿真:用四阶龙格库塔法计算传递函数状态方程的结果
- (已解决)INSTALL_FAILED_CONFLICTING_PROVIDER虚拟机安装失败错误
- PS不改变图片分辨率条件下改变照片kb大小
- pose_subscriber.cpp
- Codeforces Round #439 (Div. 2) E. The Untended Antiquity (hash+数状数组)
- java中jar文件
- Qt(mingw)+GDAL位图转矢量图写入shp或json文件