思路:

socket必须要随项目启动时启动,所以需用Spring自带的监听器,需要保持长连接,要用死循环,所以必须另外起线程,不能阻碍主线程运行

1.在项目的web.xml中配置listener

  1. <listener>
  2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  3. </listener>
  4. <listener>
  5. <listener-class>com.ra.car.utils.MyListener</listener-class>
  6. </listener>

2.因为是一个独立的线程,所以需要调用的注入类不能通过@resource或@aotowire注入,需要应用上下文获取

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:mvc="http://www.springframework.org/schema/mvc"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xmlns:tx="http://www.springframework.org/schema/tx"
  8. xmlns:task="http://www.springframework.org/schema/task"
  9. xsi:schemaLocation="http://www.springframework.org/schema/beans
  10. http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  11. http://www.springframework.org/schema/mvc
  12. http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
  13. http://www.springframework.org/schema/context
  14. http://www.springframework.org/schema/context/spring-context-4.0.xsd
  15. http://www.springframework.org/schema/aop
  16. http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
  17. http://www.springframework.org/schema/tx
  18. http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
  19. http://www.springframework.org/schema/task
  20. http://www.springframework.org/schema/task/spring-task-4.0.xsd">
  21.  
  22. <!-- 扫描包加载Service实现类 -->
  23. <context:component-scan base-package="com.ra.*.service.impl"></context:component-scan>
  24. <bean id="DataCallBackService" class="com.ra.truck.service.impl.DataCallBackServiceImpl"/>
  25. <bean id="RdTrackInfoService" class="com.ra.truck.service.impl.RdTrackInfoServiceImpl"/>
  26. <bean id="OutInterfaceService" class="com.ra.truck.service.impl.OutInterfaceImpl"/>
  27. <bean id="RdPhotoInfoService" class="com.ra.truck.service.impl.RdPhotoInfoServiceImpl"/>
  28. <bean id="MessagePackegerService" class="com.ra.truck.service.impl.MessagePackegerServiceImpl"/>
  29. <!--<bean id="redis" class="com.ra.redis.service.impl.JedisClientCluster"/>-->
  30. </beans>

  

3.创建listener监听器类

  1. package com.ra.car.utils;
  2.  
  3. import javax.servlet.ServletContextEvent;
  4. import javax.servlet.ServletContextListener;
  5.  
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8.  
  9. import com.ra.car.rabbitMQ.PBWRabbitMQCustomer;
  10. import com.ra.car.rabbitMQ.RabbitMQCustomer;
  11.  
  12. /**
  13. * listener监听器类
  14. *
  15. */
  16. public class MyListener implements ServletContextListener {
  17.  
  18. protected static final Logger logge = LoggerFactory
  19. .getLogger(MyListener.class);
  20.  
  21. @Override
  22. public void contextInitialized(ServletContextEvent arg0) {
  23. //必须单独启线程去跑listener
  24. Mythread myThread = new Mythread();
  25. //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
  26. // ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  27. // cachedThreadPool.execute(myThread);
  28. Thread thread = new Thread(myThread);
  29. thread.start();
  30. //启动MQTT
  31. // MQTTSubMsg client = new MQTTSubMsg();
  32. // client.start();
  33. RabbitMQCustomer customer=new RabbitMQCustomer();
  34. Thread threadCustomer = new Thread(customer);
  35. threadCustomer.start();
  36.  
  37. PBWRabbitMQCustomer pbwcustomer=new PBWRabbitMQCustomer();
  38. Thread pbwT = new Thread(pbwcustomer);
  39. pbwT.start();
  40. }
  41.  
  42. @Override
  43. public void contextDestroyed(ServletContextEvent arg0) {
  44. logge.info("进入ListenerUtil的contextDestroyed方法.........");
  45. }
  46.  
  47. }
  1. package com.ra.car.utils;
  2.  
  3. import java.io.IOException;
  4. import java.net.ServerSocket;
  5. import java.net.Socket;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Date;
  8.  
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11.  
  12. /**
  13. * 多线程类
  14. *
  15. */
  16. public class Mythread implements Runnable{
  17.  
  18. protected static final Logger logge = LoggerFactory
  19. .getLogger(Mythread.class);
  20.  
  21. @Override
  22. public void run() {
  23. logge.info("进入ListenerUtil的contextInitialized方法.........");
  24. try {
  25. ServerSocket serverSocket = new ServerSocket(8888);
  26. logge.info("socket通信服务端已启动,等待客户端连接.......");
  27. logge.info("我是111111111111111");
  28. while (true) {
  29. Socket socket = serverSocket.accept();// 侦听并接受到此套接字的连接,返回一个Socket对象
  30. JavaTCPServer socketThread = new JavaTCPServer(socket);
  31. socketThread.run();
  32. try {
  33. //休眠10毫秒,压力测试50000次连接无压力
  34. Thread.sleep(10);
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. } catch (IOException e) {
  40. logge.error("通信服务器启动失败!", e);
  41. }
  42. }
  43. public static String stampToDate(String s){
  44. Long timestamp = Long.parseLong(s)*1000;
  45. String date = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(timestamp));
  46.  
  47. return date;
  48. }
  49.  
  50. }
  1. package com.ra.car.utils;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.io.OutputStream;
  8. import java.io.PrintWriter;
  9. import java.net.Socket;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.concurrent.ExecutorService;
  15. import java.util.concurrent.Executors;
  16.  
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20.  
  21. public class JavaTCPServer {
  22. protected static final Logger logger=LoggerFactory.getLogger(JavaTCPServer.class);
  23.  
  24. private Socket socket;
  25.  
  26. public JavaTCPServer(Socket socket) {
  27. this.socket = socket;
  28. }
  29.  
  30. public void run() {
  31. MyThread2 myThread2=null;
  32. try {
  33. myThread2 = new MyThread2(socket);
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
  38. cachedThreadPool.execute(myThread2);
  39. }
  40.  
  41. }
  1. package com.ra.car.utils;
  2.  
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONArray;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.ra.truck.model.RdDeviceCallBackDataDomain;
  7. import com.ra.truck.service.DataCallBackService;
  8. import com.ra.truck.service.RdPhotoInfoService;
  9. import com.ra.truck.service.RdTrackInfoService;
  10. import com.ra.truck.service.outInterface.OutInterfaceService;
  11. import org.apache.commons.lang3.StringUtils;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.web.context.ContextLoader;
  15.  
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.io.OutputStream;
  19. import java.io.PrintWriter;
  20. import java.net.Socket;
  21. import java.text.SimpleDateFormat;
  22. import java.util.*;
  23.  
  24. public class MyThread2 implements Runnable {
  25.  
  26. protected static final Logger logger = LoggerFactory
  27. .getLogger(MyThread2.class);
  28.  
  29. private Socket socket;
  30. private InputStream inputStream;
  31. private OutputStream outputStream;
  32. private PrintWriter printWriter;
  33.  
  34. private int totalCount; //总数量
  35.  
  36. private int adasCount; // 传输的ADAS信号数量
  37. private int gpsCount; // 传输的GPS信号数量
  38. private DataCallBackService dataCallBackService;//数据回传private SimpleDateFormat df;
  39.  
  40. public MyThread2(Socket socket) throws IOException {
  41. this.socket = socket;
  42. inputStream = socket.getInputStream();
  43. outputStream = socket.getOutputStream();
  44. printWriter = new PrintWriter(outputStream);
  45.  
  46. dataCallBackService=(DataCallBackService)
  47. ContextLoader.getCurrentWebApplicationContext().getBean("DataCallBackService");
  48. df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  49. }
  50.  
  51. @Override
  52. public void run() {
  53. // 根据输入输出流和客户端连接
  54.  
  55. // 得到一个输入流,接收客户端传递的信息
  56. // InputStreamReader inputStreamReader = new InputStreamReader(
  57. // inputStream);// 提高效率,将自己字节流转为字符流
  58. // bufferedReader = new BufferedReader(inputStreamReader);// 加入缓冲区
  59. Date timestart = new Date();
  60. Date timeend = null;
  61. long minuine = 0;
  62. int count = 0;
  63. while (true) {
  64. try {
  65. if (inputStream.available() > 0 == false) {
  66. timeend = new Date();
  67. minuine = timeend.getTime() - timestart.getTime();
  68. if (minuine != 0 && (minuine / 1000) > 60) {
  69. break;
  70. }
  71. continue;
  72. } else {
  73. timestart = new Date();
  74. try {
  75. Thread.sleep(200);
  76. } catch (InterruptedException e) {
  77. logger.error("*****线程休眠出现异常*****", e);
  78. }
  79. count = inputStream.available();
  80. byte[] b = new byte[count];
  81. int readCount = 0; // 已经成功读取的字节的个数
  82. while (readCount < count) {
  83. readCount += inputStream.read(b, readCount, count
  84. - readCount);
  85. }
  86. logger.info("**********当前服务器正在被连接**********");
  87. logger.info("正在连接的客户端IP为:"
  88. + socket.getInetAddress().getHostAddress());
  89.  
  90. logger.info("当前时间为:" + df.format(new Date()));
  91. String data = new String(b, "utf-8");
  92. logger.info("传输过来的info:" + data);
  93. String id = jsonStringToObject(data);
  94. Map<Object, Object> map = new HashMap<Object, Object>();
  95. //心跳发送不带id的json数据
  96. if (StringUtils.isNotBlank(id)) {
  97. map.put("id", id);
  98. }
  99. map.put("resultCode", "1");
  100. map.put("result", "success");
  101. printWriter.print(JSON.toJSONString(map) + "\n");
  102. printWriter.flush();
  103. }
  104. } catch (Exception e) {
  105. logger.error("数据传输出现异常", e);
  106. try {
  107. outputStream = socket.getOutputStream();
  108. } catch (IOException e1) {
  109. logger.error("获取outputStream出现异常");
  110. }
  111. // 获取一个输出流,向服务端发送信息
  112. // printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
  113. Map<Object, Object> map = new HashMap<Object, Object>();
  114. map.put("resultCode", "0");
  115. map.put("result", "fail");
  116. printWriter.print(JSON.toJSONString(map) + "\n");
  117. printWriter.flush();
  118. }
  119. }
  120. try {
  121. printWriter.close();
  122. outputStream.close();
  123. inputStream.close();
  124. logger.info("30s没有发送数据,服务端主动关闭连接");
  125. logger.info("被断开的客户端IP为:"
  126. + socket.getInetAddress().getHostAddress());
  127. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  128. logger.info("被断开的时间为:" + df.format(new Date()));
  129. socket.close();
  130. } catch (IOException e) {
  131. logger.error("关闭socket出现异常", e);
  132.  
  133. }
  134.  
  135. /*
  136. * while ((temp = bufferedReader.readLine()) != null) { info += temp;
  137. * logger.info(bufferedReader.readLine());
  138. * logger.info("已接收到客户端连接!!!!!!"); logger.info("服务端接收到客户端信息:" +
  139. * info + ",当前客户端ip为:" + socket.getInetAddress().getHostAddress());
  140. * logger.info("服务端接收到客户端信息:" + info + ",当前客户端ip为:" +
  141. * socket.getInetAddress().getHostAddress()); }
  142. */
  143.  
  144. /*
  145. * logger.info("*****测试Redis*****"); JedisClient
  146. * jedisClient=(JedisClient)
  147. * ContextLoader.getCurrentWebApplicationContext().getBean("redis");
  148. * jedisClient.set("testLanHao", "123456789"); String
  149. * str=jedisClient.get("testLanHao");
  150. * logger.info("从Redis中取得数据为:"+str);
  151. * logger.info("*****测试Redis*****");
  152. */
  153.  
  154. // ApplicationContext applicationContext=new
  155. // ClassPathXmlApplicationContext("classpath*:applicationContext-*.xml");
  156. // RiskManageService
  157. // riskManageService=applicationContext.getBean(RiskManageService.class);
  158. // socket单独线程,需要重新加载上下文,扫描的类在applicationContext-service.xml配置
  159. /*
  160. * RiskManageService riskManageService=(RiskManageService)
  161. * ContextLoader.getCurrentWebApplicationContext().getBean("risk");
  162. * RdRiskEventInfo rdRiskEventInfo=new RdRiskEventInfo();
  163. * rdRiskEventInfo.setId("10"); try { List<RdPhotoInfo>
  164. * list=riskManageService.findPhotoInfoByEventId(rdRiskEventInfo);
  165. * logger.info(list); } catch (ServiceException e) {
  166. * e.printStackTrace(); }
  167. */
  168. // outputStream = socket.getOutputStream();// 获取一个输出流,向服务端发送信息
  169. // printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
  170.  
  171. }
  172.  
  173. private String jsonStringToObject(String data) {
  174. //数据解析方法return xx;
  175. }
  176. public static Date stampToDate(String s){
  177.  
  178. Long timestamp = Long.parseLong(s)*1000;
  179. Date date = new Date(timestamp);
  180.  
  181. return date;
  182. }

基于TCP/IP协议的socket通讯server的更多相关文章

  1. 基于TCP/IP协议的socket通讯client

    package com.ra.car.utils; import java.io.BufferedReader; import java.io.IOException; import java.io. ...

  2. http、TCP/IP协议与socket之间的区别

    http.TCP/IP协议与socket之间的区别     网络由下往上分为:  www.2cto.com   物理层--                       数据链路层-- 网络层--   ...

  3. 基于TCP/IP协议的C++网络编程(API函数版)

    源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...

  4. http、TCP/IP协议与socket之间的区别(转载)

    http.TCP/IP协议与socket之间的区别  https://www.cnblogs.com/iOS-mt/p/4264675.html http.TCP/IP协议与socket之间的区别   ...

  5. JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

    OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...

  6. TCP/IP协议与Socket

    1.计算机网络体系结构分层 OSI 参考模型注重"通信协议必要的功能是什么", TCP/IP 则更强调"在计算机上实现协议应该开发哪种程序". 2.TCP/IP ...

  7. c# TCP/IP协议利用Socket Client通信(只含客户端Demo)

    完全是基础,新手可以随意看看,大牛可以关闭浏览页了,哈哈. TCP/IP协议 TCP/IP是一系列网络通信协议的统称,其中最核心的两个协议是TCP和IP.TCP称为传输控制协议,IP称为互联网络协议. ...

  8. 读书笔记——网络编程与开发技术(3)基于TCP/IP协议的网络编程相关知识

    TCP/IP协议:数据链路层,网络层,传输层,应用层. IP地址分为5类:A类.B类.C类.D类.E类. (A类.B类.C类是基本类,D类多用于多播传送,E类为保留类.) "*"表 ...

  9. 标准C实现基于TCP/IP协议的文件传输

    上学期集成程序设计的课堂作业,对于理解TCP/IP实现还是挺有帮助的. TCP/IP编程实现远程文件传输在LUNIX中一般都采用套接字(socket)系统调用. 采用客户/服务器模式,其程序编写步骤如 ...

随机推荐

  1. 九九乘法表python3写入文件中

    写入文件代码如下: with open("e:\\test01.txt","w+",encoding="utf-8") as wq: for ...

  2. 洛谷P3295 萌萌哒 [SCOI2016] 倍增+并查集

    正解:倍增+并查集 解题报告: 传送门! 首先不难想到暴力?就考虑把区间相等转化成对应点对相等,然后直接对应点连边,最后求有几个连通块就好辣 然后看下复杂度,修改是O(n2)查询是O(n),就比较容易 ...

  3. 产品列表中使用v-lazyload插件懒加载img图片,但是当产品列表重新排序(人气,销量,价格...),产品info信息改变,但是 img 图片没有发生变化;

    1.控制台查看 DOM 结构,发现 DOM 绑定的图片链接也没有发生变化: 2.查阅资料找到解决方法,只需要在 img 标签中增加 :key='imgUrl',即可实现 img 图片随数据排序的改变动 ...

  4. webpack导入css及各项loader

    1. webpack导入css 1) 下载相关的加载器 npm install style-loader css-loader -D 2)将index.css引入到mian.js中 import '. ...

  5. spring学习(03)之bean实例化的三种方式

    bean实体例化的三种方式 在spring中有三中实例化bean的方式: 一.使用构造器实例化:(通常使用的一个方法,重点) 二.使用静态工厂方法实例化: 三.使用实例化工厂方法实例化 第一种.使用构 ...

  6. 1-4-bootloader架构学习

    1-4-bootloader架构学习 1.一般情况下嵌入式 Linux 系统中的软件主要分为以下几部分: 1) 引导加载程序:其中包括内部 ROM 中的固化启动代码和 BootLoader 两部分. ...

  7. Redis和Memcache的区别是什么

    Redis和Memcache都是内存数据库,但它们之间还是有区别的,跟着ytkah看看Redis和Memcache的区别吧 Redis 支持多种数据结构,如string,list,dict,set,z ...

  8. 20180820 JS 片段

    $.post异步发送容易引起后台没有处理完,就提示错误异常.在不必要的情况下,请采用.同步的方式 $.ajaxSetup({ async: false }); 但在$.post结束后记得恢复系统默认的 ...

  9. SQL SERVER 2016研究二

    2.动态数据屏蔽 创建数据表: 创建账号并授予获取屏蔽后数据的权限 此函数:partial(0,"XXX-XXXX-",4) 表示从左边0位开始依次替换到倒数4位. 注意:屏蔽只作 ...

  10. 照葫芦画瓢之爬虫豆瓣top100

    import requestsimport reimport jsonfrom requests.exceptions import RequestExceptiondef get(url):    ...