基于TCP/IP协议的socket通讯server
思路:
socket必须要随项目启动时启动,所以需用Spring自带的监听器,需要保持长连接,要用死循环,所以必须另外起线程,不能阻碍主线程运行
1.在项目的web.xml中配置listener
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <listener>
- <listener-class>com.ra.car.utils.MyListener</listener-class>
- </listener>
2.因为是一个独立的线程,所以需要调用的注入类不能通过@resource或@aotowire注入,需要应用上下文获取
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:task="http://www.springframework.org/schema/task"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
- http://www.springframework.org/schema/task
- http://www.springframework.org/schema/task/spring-task-4.0.xsd">
- <!-- 扫描包加载Service实现类 -->
- <context:component-scan base-package="com.ra.*.service.impl"></context:component-scan>
- <bean id="DataCallBackService" class="com.ra.truck.service.impl.DataCallBackServiceImpl"/>
- <bean id="RdTrackInfoService" class="com.ra.truck.service.impl.RdTrackInfoServiceImpl"/>
- <bean id="OutInterfaceService" class="com.ra.truck.service.impl.OutInterfaceImpl"/>
- <bean id="RdPhotoInfoService" class="com.ra.truck.service.impl.RdPhotoInfoServiceImpl"/>
- <bean id="MessagePackegerService" class="com.ra.truck.service.impl.MessagePackegerServiceImpl"/>
- <!--<bean id="redis" class="com.ra.redis.service.impl.JedisClientCluster"/>-->
- </beans>
3.创建listener监听器类
- package com.ra.car.utils;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.ra.car.rabbitMQ.PBWRabbitMQCustomer;
- import com.ra.car.rabbitMQ.RabbitMQCustomer;
- /**
- * listener监听器类
- *
- */
- public class MyListener implements ServletContextListener {
- protected static final Logger logge = LoggerFactory
- .getLogger(MyListener.class);
- @Override
- public void contextInitialized(ServletContextEvent arg0) {
- //必须单独启线程去跑listener
- Mythread myThread = new Mythread();
- //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
- // ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
- // cachedThreadPool.execute(myThread);
- Thread thread = new Thread(myThread);
- thread.start();
- //启动MQTT
- // MQTTSubMsg client = new MQTTSubMsg();
- // client.start();
- RabbitMQCustomer customer=new RabbitMQCustomer();
- Thread threadCustomer = new Thread(customer);
- threadCustomer.start();
- PBWRabbitMQCustomer pbwcustomer=new PBWRabbitMQCustomer();
- Thread pbwT = new Thread(pbwcustomer);
- pbwT.start();
- }
- @Override
- public void contextDestroyed(ServletContextEvent arg0) {
- logge.info("进入ListenerUtil的contextDestroyed方法.........");
- }
- }
- package com.ra.car.utils;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- * 多线程类
- *
- */
- public class Mythread implements Runnable{
- protected static final Logger logge = LoggerFactory
- .getLogger(Mythread.class);
- @Override
- public void run() {
- logge.info("进入ListenerUtil的contextInitialized方法.........");
- try {
- ServerSocket serverSocket = new ServerSocket(8888);
- logge.info("socket通信服务端已启动,等待客户端连接.......");
- logge.info("我是111111111111111");
- while (true) {
- Socket socket = serverSocket.accept();// 侦听并接受到此套接字的连接,返回一个Socket对象
- JavaTCPServer socketThread = new JavaTCPServer(socket);
- socketThread.run();
- try {
- //休眠10毫秒,压力测试50000次连接无压力
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- } catch (IOException e) {
- logge.error("通信服务器启动失败!", e);
- }
- }
- public static String stampToDate(String s){
- Long timestamp = Long.parseLong(s)*1000;
- String date = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(timestamp));
- return date;
- }
- }
- package com.ra.car.utils;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.PrintWriter;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class JavaTCPServer {
- protected static final Logger logger=LoggerFactory.getLogger(JavaTCPServer.class);
- private Socket socket;
- public JavaTCPServer(Socket socket) {
- this.socket = socket;
- }
- public void run() {
- MyThread2 myThread2=null;
- try {
- myThread2 = new MyThread2(socket);
- } catch (IOException e) {
- e.printStackTrace();
- }
- ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
- cachedThreadPool.execute(myThread2);
- }
- }
- package com.ra.car.utils;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.ra.truck.model.RdDeviceCallBackDataDomain;
- import com.ra.truck.service.DataCallBackService;
- import com.ra.truck.service.RdPhotoInfoService;
- import com.ra.truck.service.RdTrackInfoService;
- import com.ra.truck.service.outInterface.OutInterfaceService;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.context.ContextLoader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.PrintWriter;
- import java.net.Socket;
- import java.text.SimpleDateFormat;
- import java.util.*;
- public class MyThread2 implements Runnable {
- protected static final Logger logger = LoggerFactory
- .getLogger(MyThread2.class);
- private Socket socket;
- private InputStream inputStream;
- private OutputStream outputStream;
- private PrintWriter printWriter;
- private int totalCount; //总数量
- private int adasCount; // 传输的ADAS信号数量
- private int gpsCount; // 传输的GPS信号数量
- private DataCallBackService dataCallBackService;//数据回传private SimpleDateFormat df;
- public MyThread2(Socket socket) throws IOException {
- this.socket = socket;
- inputStream = socket.getInputStream();
- outputStream = socket.getOutputStream();
- printWriter = new PrintWriter(outputStream);
- dataCallBackService=(DataCallBackService)
- ContextLoader.getCurrentWebApplicationContext().getBean("DataCallBackService");
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- }
- @Override
- public void run() {
- // 根据输入输出流和客户端连接
- // 得到一个输入流,接收客户端传递的信息
- // InputStreamReader inputStreamReader = new InputStreamReader(
- // inputStream);// 提高效率,将自己字节流转为字符流
- // bufferedReader = new BufferedReader(inputStreamReader);// 加入缓冲区
- Date timestart = new Date();
- Date timeend = null;
- long minuine = 0;
- int count = 0;
- while (true) {
- try {
- if (inputStream.available() > 0 == false) {
- timeend = new Date();
- minuine = timeend.getTime() - timestart.getTime();
- if (minuine != 0 && (minuine / 1000) > 60) {
- break;
- }
- continue;
- } else {
- timestart = new Date();
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- logger.error("*****线程休眠出现异常*****", e);
- }
- count = inputStream.available();
- byte[] b = new byte[count];
- int readCount = 0; // 已经成功读取的字节的个数
- while (readCount < count) {
- readCount += inputStream.read(b, readCount, count
- - readCount);
- }
- logger.info("**********当前服务器正在被连接**********");
- logger.info("正在连接的客户端IP为:"
- + socket.getInetAddress().getHostAddress());
- logger.info("当前时间为:" + df.format(new Date()));
- String data = new String(b, "utf-8");
- logger.info("传输过来的info:" + data);
- String id = jsonStringToObject(data);
- Map<Object, Object> map = new HashMap<Object, Object>();
- //心跳发送不带id的json数据
- if (StringUtils.isNotBlank(id)) {
- map.put("id", id);
- }
- map.put("resultCode", "1");
- map.put("result", "success");
- printWriter.print(JSON.toJSONString(map) + "\n");
- printWriter.flush();
- }
- } catch (Exception e) {
- logger.error("数据传输出现异常", e);
- try {
- outputStream = socket.getOutputStream();
- } catch (IOException e1) {
- logger.error("获取outputStream出现异常");
- }
- // 获取一个输出流,向服务端发送信息
- // printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
- Map<Object, Object> map = new HashMap<Object, Object>();
- map.put("resultCode", "0");
- map.put("result", "fail");
- printWriter.print(JSON.toJSONString(map) + "\n");
- printWriter.flush();
- }
- }
- try {
- printWriter.close();
- outputStream.close();
- inputStream.close();
- logger.info("30s没有发送数据,服务端主动关闭连接");
- logger.info("被断开的客户端IP为:"
- + socket.getInetAddress().getHostAddress());
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- logger.info("被断开的时间为:" + df.format(new Date()));
- socket.close();
- } catch (IOException e) {
- logger.error("关闭socket出现异常", e);
- }
- /*
- * while ((temp = bufferedReader.readLine()) != null) { info += temp;
- * logger.info(bufferedReader.readLine());
- * logger.info("已接收到客户端连接!!!!!!"); logger.info("服务端接收到客户端信息:" +
- * info + ",当前客户端ip为:" + socket.getInetAddress().getHostAddress());
- * logger.info("服务端接收到客户端信息:" + info + ",当前客户端ip为:" +
- * socket.getInetAddress().getHostAddress()); }
- */
- /*
- * logger.info("*****测试Redis*****"); JedisClient
- * jedisClient=(JedisClient)
- * ContextLoader.getCurrentWebApplicationContext().getBean("redis");
- * jedisClient.set("testLanHao", "123456789"); String
- * str=jedisClient.get("testLanHao");
- * logger.info("从Redis中取得数据为:"+str);
- * logger.info("*****测试Redis*****");
- */
- // ApplicationContext applicationContext=new
- // ClassPathXmlApplicationContext("classpath*:applicationContext-*.xml");
- // RiskManageService
- // riskManageService=applicationContext.getBean(RiskManageService.class);
- // socket单独线程,需要重新加载上下文,扫描的类在applicationContext-service.xml配置
- /*
- * RiskManageService riskManageService=(RiskManageService)
- * ContextLoader.getCurrentWebApplicationContext().getBean("risk");
- * RdRiskEventInfo rdRiskEventInfo=new RdRiskEventInfo();
- * rdRiskEventInfo.setId("10"); try { List<RdPhotoInfo>
- * list=riskManageService.findPhotoInfoByEventId(rdRiskEventInfo);
- * logger.info(list); } catch (ServiceException e) {
- * e.printStackTrace(); }
- */
- // outputStream = socket.getOutputStream();// 获取一个输出流,向服务端发送信息
- // printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
- }
- private String jsonStringToObject(String data) {
- //数据解析方法return xx;
- }
- public static Date stampToDate(String s){
- Long timestamp = Long.parseLong(s)*1000;
- Date date = new Date(timestamp);
- return date;
- }
基于TCP/IP协议的socket通讯server的更多相关文章
- 基于TCP/IP协议的socket通讯client
package com.ra.car.utils; import java.io.BufferedReader; import java.io.IOException; import java.io. ...
- http、TCP/IP协议与socket之间的区别
http.TCP/IP协议与socket之间的区别 网络由下往上分为: www.2cto.com 物理层-- 数据链路层-- 网络层-- ...
- 基于TCP/IP协议的C++网络编程(API函数版)
源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...
- http、TCP/IP协议与socket之间的区别(转载)
http.TCP/IP协议与socket之间的区别 https://www.cnblogs.com/iOS-mt/p/4264675.html http.TCP/IP协议与socket之间的区别 ...
- JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo
OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...
- TCP/IP协议与Socket
1.计算机网络体系结构分层 OSI 参考模型注重"通信协议必要的功能是什么", TCP/IP 则更强调"在计算机上实现协议应该开发哪种程序". 2.TCP/IP ...
- c# TCP/IP协议利用Socket Client通信(只含客户端Demo)
完全是基础,新手可以随意看看,大牛可以关闭浏览页了,哈哈. TCP/IP协议 TCP/IP是一系列网络通信协议的统称,其中最核心的两个协议是TCP和IP.TCP称为传输控制协议,IP称为互联网络协议. ...
- 读书笔记——网络编程与开发技术(3)基于TCP/IP协议的网络编程相关知识
TCP/IP协议:数据链路层,网络层,传输层,应用层. IP地址分为5类:A类.B类.C类.D类.E类. (A类.B类.C类是基本类,D类多用于多播传送,E类为保留类.) "*"表 ...
- 标准C实现基于TCP/IP协议的文件传输
上学期集成程序设计的课堂作业,对于理解TCP/IP实现还是挺有帮助的. TCP/IP编程实现远程文件传输在LUNIX中一般都采用套接字(socket)系统调用. 采用客户/服务器模式,其程序编写步骤如 ...
随机推荐
- 九九乘法表python3写入文件中
写入文件代码如下: with open("e:\\test01.txt","w+",encoding="utf-8") as wq: for ...
- 洛谷P3295 萌萌哒 [SCOI2016] 倍增+并查集
正解:倍增+并查集 解题报告: 传送门! 首先不难想到暴力?就考虑把区间相等转化成对应点对相等,然后直接对应点连边,最后求有几个连通块就好辣 然后看下复杂度,修改是O(n2)查询是O(n),就比较容易 ...
- 产品列表中使用v-lazyload插件懒加载img图片,但是当产品列表重新排序(人气,销量,价格...),产品info信息改变,但是 img 图片没有发生变化;
1.控制台查看 DOM 结构,发现 DOM 绑定的图片链接也没有发生变化: 2.查阅资料找到解决方法,只需要在 img 标签中增加 :key='imgUrl',即可实现 img 图片随数据排序的改变动 ...
- webpack导入css及各项loader
1. webpack导入css 1) 下载相关的加载器 npm install style-loader css-loader -D 2)将index.css引入到mian.js中 import '. ...
- spring学习(03)之bean实例化的三种方式
bean实体例化的三种方式 在spring中有三中实例化bean的方式: 一.使用构造器实例化:(通常使用的一个方法,重点) 二.使用静态工厂方法实例化: 三.使用实例化工厂方法实例化 第一种.使用构 ...
- 1-4-bootloader架构学习
1-4-bootloader架构学习 1.一般情况下嵌入式 Linux 系统中的软件主要分为以下几部分: 1) 引导加载程序:其中包括内部 ROM 中的固化启动代码和 BootLoader 两部分. ...
- Redis和Memcache的区别是什么
Redis和Memcache都是内存数据库,但它们之间还是有区别的,跟着ytkah看看Redis和Memcache的区别吧 Redis 支持多种数据结构,如string,list,dict,set,z ...
- 20180820 JS 片段
$.post异步发送容易引起后台没有处理完,就提示错误异常.在不必要的情况下,请采用.同步的方式 $.ajaxSetup({ async: false }); 但在$.post结束后记得恢复系统默认的 ...
- SQL SERVER 2016研究二
2.动态数据屏蔽 创建数据表: 创建账号并授予获取屏蔽后数据的权限 此函数:partial(0,"XXX-XXXX-",4) 表示从左边0位开始依次替换到倒数4位. 注意:屏蔽只作 ...
- 照葫芦画瓢之爬虫豆瓣top100
import requestsimport reimport jsonfrom requests.exceptions import RequestExceptiondef get(url): ...