思路:

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的更多相关文章

  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. tensorflow入门笔记(三) tf.GraphKeys

    tf.GraphKeys类存放了图集用到的标准名称. 该标准库使用各种已知的名称收集和检索图中相关的值.例如,tf.Optimizer子类在没有明确指定待优化变量的情况下默认优化被收集到tf.Grap ...

  2. 运行python文件时出错SyntaxError: Non-UTF-8 code starting with '\xb5' in file, but no encoding declared;

    今天ytkah在运行python文件时出现错误,提示如下,很明显这是没有定义python文件编码引起的问题,那么要怎么解决呢?很简单,在文件头部定义一下就可以了. File "hello.p ...

  3. 看大师解说Android高速开发框架EasyAndroid

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u010966622/article/details/37601789 前几天做了小应用.感觉小有成就 ...

  4. NYOJ 最长公共子序列

    # include<iostream> # include<string> # include<stdio.h> using namespace std; ][]; ...

  5. python的__all__

    用来暴露接口 控制 from xxx import * 的行为 代码中当然是不提倡用 from xxx import * 的写法的,但是在 console 调试的时候图个方便还是很常见的.如果一个模块 ...

  6. ie6-ie8支持CSS3选择器的解决办法

    引入nwmatcher.js和selectivizr.js <!--[if lt IE 10]> <script src="html5shiv.js">&l ...

  7. LINUX的DNS怎么设置?linux下如何修改DNS地址

    LINUX的DNS怎么设置?linux下如何修改DNS地址 https://jingyan.baidu.com/article/870c6fc32c028eb03fe4be30.html Linux下 ...

  8. Json常用操作

    1, 获取json字符串中属性(传统方式) import net.sf.json.JSONObject JSONObject json = JSONObject.fromObject(response ...

  9. Wix制作安装包

    Wix制作安装包,找起资料来很费劲,记录一下: Product.wxs,该文件只能制作出msi形式的安装包,不能做到自动检测framework. <?xml version="1.0& ...

  10. Extjs event domain 研究

    Listeners and Event Domains In Ext JS 4.2, the MVC event dispatcher was generalized with the introdu ...