Java Socket长连接示例代码
SocketListenerPusher.java代码如下:
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
- import org.apache.commons.configuration.ConfigurationException;
- import org.directwebremoting.impl.DaemonThreadFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.shihuan.dragonkeeper.common.utils.PropertiesUtil;
- import com.shihuan.dragonkeeper.global.ConfigFile;
- public class SocketListenerPusher implements Runnable {
- protected static Logger logger = LoggerFactory.getLogger(SocketListenerPusher.class);
- public static String socketlistenerserver_CONFIG = ConfigFile.SOCKETLISTENERSERVER__CONFIG + ConfigFile.SUFFIX_NAME;
- private ServerSocket serverSocket;
- private ExecutorService pool;
- public SocketListenerPusher() {
- int port = 0;
- int poolsize = 0;
- try {
- port = Integer.parseInt(PropertiesUtil.getPropertiesValue(socketlistenerserver_CONFIG, "serverport"));
- poolsize = Integer.parseInt(PropertiesUtil.getPropertiesValue(socketlistenerserver_CONFIG, "poolsize"));
- serverSocket = new ServerSocket();
- serverSocket.setReuseAddress(true);
- serverSocket.bind(new InetSocketAddress(port));
- pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * poolsize);
- //下面两句循环执行run()方法, 相当于while(true){...}
- ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, new DaemonThreadFactory());
- executor.scheduleAtFixedRate(this, 1L, 1L, TimeUnit.MILLISECONDS);
- } catch (NumberFormatException e) {
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- } catch (ConfigurationException e) {
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- }
- }
- public void run() {
- Socket socket = null;
- try {
- socket = serverSocket.accept();
- pool.execute(new SocketListenerHandler(socket));
- } catch (IOException e) {
- System.out.println("线程池被关闭!!!!!!!!!!!");
- pool.shutdown();
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- }
- }
SocketListenerHandler.java代码如下:
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.ObjectInputStream;
- import java.net.Socket;
- import java.sql.Connection;
- import java.sql.SQLException;
- import org.apache.commons.configuration.ConfigurationException;
- import org.apache.commons.dbutils.DbUtils;
- import org.apache.commons.dbutils.QueryRunner;
- import org.apache.commons.io.IOUtils;
- import org.directwebremoting.Browser;
- import org.directwebremoting.ScriptSessions;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.alibaba.fastjson.JSON;
- import com.shihuan.dragonkeeper.common.dto.DataSourceInfo;
- import com.shihuan.dragonkeeper.common.utils.ByteArrayUtil;
- import com.shihuan.dragonkeeper.common.utils.DataSourceMapUtil;
- import com.shihuan.dragonkeeper.common.utils.DateFormatterUtil;
- import com.shihuan.dragonkeeper.common.utils.PropertiesUtil;
- import com.shihuan.dragonkeeper.global.ConfigFile;
- import com.shihuan.dragonkeeper.server.bean.ActivityServiceBean;
- public class SocketListenerHandler implements Runnable {
- protected static Logger logger = LoggerFactory.getLogger(SocketListenerHandler.class);
- private static String jdbc_CONFIG = ConfigFile.JDBC_CONFIG + ConfigFile.SUFFIX_NAME;
- public static final int timeOut = 0*1000 ; //设置读取操作异常为1秒
- private final String dataRealTimeAction_id = "Agentdata_" + Math.random();
- private static final String noData = "{'nodata':'心跳信息'}";
- private static final String errorData = "{'error':'无法解析的请求'}";
- private Socket connectedsocket = null;
- public SocketListenerHandler(Socket socket){
- this.connectedsocket = socket;
- }
- @Override
- public void run() {
- BufferedReader in = null;
- String resultData = "";
- try {
- connectedsocket.setSoTimeout(timeOut); //表示接收数据时的等待超时数据, 此方法必须在接收数据之前执行才有效. 此外, 当输入流的 read()方法抛出 SocketTimeoutException后, Socket仍然是连接的, 可以尝试再次读数据, 单位为毫秒, 它的默认值为 0(表示会无限等待, 永远不会超时)
- connectedsocket.setKeepAlive(false); //表示对于长时间处于空闲状态的Socket, 是否要自动把它关闭.
- in = new BufferedReader(new InputStreamReader(connectedsocket.getInputStream()));
- if (in.ready()) { //判断流中是否有数据
- resultData = getNoHeadData(in.readLine()); //从Agent端接收到的数据
- logger.info("#### 结果DATA = "+resultData);
- if (resultData==null || "".equals(resultData)) {
- logger.info(dataRealTimeAction_id + " -->>> " + "内容为空!");
- } else if (resultData.charAt(0) != '{') { //要在客户端定时维持心跳信息
- logger.info(dataRealTimeAction_id + " -->>> " + noData);
- } else {
- ActivityServiceBean asb = JSON.parseObject(resultData, ActivityServiceBean.class);
- System.out.println("打印预处理信息Start......");
- System.out.println(asb.getProxyname() + " -- " + asb.getIp() + " -- " + asb.getCalltime() + " -- " + asb.getAnswertime() + " -- " + asb.getCpu() + " -- " + asb.getThread() + " -- " + asb.getStatus() + " -- " + asb.getAccessaddress() + " -- " + asb.getAccessfilename() + " -- " + asb.getSql() + " -- " + asb.getContent());
- System.out.println("打印预处理信息End......");
- // parseData(ois);
- logger.info(dataRealTimeAction_id + ": 成功处理了接收到的数据!");
- }
- }
- } catch (IOException e) {
- logger.error(e.getMessage() + " " + errorData, e);
- e.printStackTrace();
- } catch (NumberFormatException e) {
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
- e.printStackTrace();
- }
- }
- }
- }
TestSocketListenerPusher.java请求端代码如下:
- import java.io.BufferedOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.util.Date;
- import org.apache.commons.configuration.ConfigurationException;
- import com.alibaba.fastjson.JSON;
- import com.shihuan.dragonkeeper.common.utils.ByteArrayUtil;
- import com.shihuan.dragonkeeper.common.utils.PropertiesUtil;
- import com.shihuan.dragonkeeper.global.ConfigFile;
- import com.shihuan.dragonkeeper.server.bean.ActivityServiceBean;
- public class TestSocketListenerPusher implements Runnable {
- private static String socketlistenerserver_CONFIG = ConfigFile.SOCKETLISTENERSERVER__CONFIG + ConfigFile.SUFFIX_NAME;
- private Socket socketclient = null;
- @Override
- public void run() {
- String serverip = "";
- int port = 0;
- OutputStream os = null;
- try {
- serverip = PropertiesUtil.getPropertiesValue(socketlistenerserver_CONFIG, "serverip");
- port = Integer.parseInt(PropertiesUtil.getPropertiesValue(socketlistenerserver_CONFIG, "serverport"));
- ActivityServiceBean asb = null;
- for (int i=0; i<2; i++) {
- asb = new ActivityServiceBean();
- asb.setProxyname("testProxyname"+i);
- asb.setIp("testIp"+i);
- Date curdate = new Date();
- asb.setCalltime(curdate);
- asb.setAnswertime(curdate);
- asb.setCpu("testCpu"+i);
- asb.setThread("testThread"+i);
- asb.setStatus("testStatus"+i);
- asb.setAccessaddress("testAccessaddress"+i);
- asb.setAccessfilename("testAccessfilename"+i);
- asb.setSql("testSql"+i);
- asb.setContent("testContent"+i);
- String jsonStr = JSON.toJSONString(asb).trim();
- byte[] information = (new String(ByteArrayUtil.getIntToByte(jsonStr.length()))+jsonStr).getBytes();
- System.out.println(information.length);
- socketclient = new Socket(serverip, port);
- socketclient.setSoTimeout(0);
- socketclient.setKeepAlive(false);
- os = new BufferedOutputStream(socketclient.getOutputStream());
- os.write(information);
- os.flush();
- System.out.println("Client" + i + " -->>> " + new String(ByteArrayUtil.getIntToByte(jsonStr.length()))+jsonStr);
- os.close();
- Thread.sleep(3000);
- }
- } catch (ConfigurationException e) {
- e.printStackTrace();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- /*
- try {
- if (os != null) {
- os.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- */
- }
- }
- public static void main(String[] args) {
- Thread t = new Thread(new TestSocketListenerPusher());
- t.start();
- }
- }
源代码在笔者shihuan8@163.com邮箱网盘中J2EE代码文件夹里。
----------------------------------------------------------------------------------
如果是按byte[]传输数据的情况,请参考如下代码:
SimpleSocketServer.java代码如下:
- package com.shihuan.socket;
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class SimpleSocketServer {
- public static void main(String[] args) {
- try {
- ServerSocket ss = new ServerSocket();
- ss.setReuseAddress(true); //两个进程共用同一个端口的时候,一个进程关闭后,另一个进程还能够立刻重用相同端口
- ss.setReceiveBufferSize(128*1024); //缓冲区中允许接收的最大字节数,默认是8192
- ss.bind(new InetSocketAddress(19990));
- Socket client = ss.accept();
- InputStream in = new BufferedInputStream(client.getInputStream());
- byte tmpb = (byte)in.read();
- System.out.println("第一个字节的byte值 --->> " + tmpb);
- System.out.println("接收字节 --->> " + in.available());
- byte[] bc = new byte[in.available()+1];
- bc[0] = tmpb;
- in.read(bc, 1, in.available());
- System.out.println(bc.length);
- System.out.println(new String(bc));
- in.close();
- } catch (IOException e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
- }
- }
- }
SimpleSocketClient.java代码如下:
- package com.shihuan.socket;
- import java.io.BufferedOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.net.UnknownHostException;
- public class SimpleSocketClient {
- public static void main(String[] args) throws UnknownHostException {
- try {
- Socket s = new Socket("192.168.1.10", 19990);
- OutputStream os = new BufferedOutputStream(s.getOutputStream());
- String info = "abc!";
- info = "大家好!";
- byte[] bi = info.getBytes();
- os.write(bi);
- os.flush();
- os.close();
- } catch (IOException e) {
- System.out.println(e.getMessage());
- e.printStackTrace();
- }
- }
- }
稍微复杂一点儿代码示例,处理了粘包问题:
StartListenerTcpThread.java代码:
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.SocketAddress;
- import java.util.Vector;
- import java.util.concurrent.ExcutorService;
- import java.util.concurrent.Excutors;
- import org.apache.commons.io.IUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.shihuan.dragonkeeper.common.utils.ByteArrayUtil;
- import com.shihuan.dragonkeeper.global.ConfigFile;
- public class StartListenerTcpThread implements Runnable {
- public static Logger logger = LoggerFactory.getLogger(StartListenerTcpThread.class);
- private static ExcutorService Threadpool = Excutors.newCachedThreadPool();
- private static boolean businessflag = true;
- private static final int receiveBufferSize = 128;
- private static Vector<byte[]> tmpbytes = new Vector<byte[]>();
- private ServerSocket serverSocket = null;
- public StartListenerTcpThread(String ip, int port){
- try{
- serverSocket = new ServerSocket();
- serverSocket.setReuseAddress(true);
- serverSocket.setReceiveBufferSize(receiveBufferSize*1024);
- serverSocket.setSoTimeout(0);
- SocketAddress sa = new InetSocketAddress(port);
- serverSocket.bind(sa, 20);
- }catch(IOException e){
- logger.error(e.getMessage(), e);
- }
- }
- public void run(){
- Socket socket = null;
- while(true){
- if(businessflag){
- try{
- socket = serverSocket.accept();
- System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
- InputStream socketIn = new BufferedInputStream(socket.getInputStream());
- byte tmpb = (byte)socketIn.read();
- byte[] currentbytes = null;
- if(tmpbytes.size() > 0){ //上一次IO流中有未处理的剩余包
- int oldBytesLen = tmpbytes.get(0).length;
- int socketBytesLen = socketIn.available()+1;
- int currentLength = oldByteLen + socketBytesLen;
- currentbytes = new byte[currentLength];
- System.arraycopy(tmpbytes.get(0), 0, currentbytes, oldBytesLen);
- currentbytes[oldBytesLen] = tmpb;
- socketIn.read(currentbytes, oldBytesLen+1, socketBytesLen-1);
- socketIn.close();
- splitInputStreamByte(currentbytes);
- }else{ //正常未粘包情况
- int socketBytesLen = socketIn.available()+1;
- currentbytes = new byte[socketBytesLen];
- currentbytes[0] = tmpb;
- socketIn.read(currentbytes, 1, socketBytesLen-1);
- socketIn.close();
- splitInputStreamByte(currentbytes);
- }
- }catch(IOException e){
- logger.error(e.getMessage(), e);
- }
- }
- }
- }
- /**
- * 拆分byte数组并分多线程处理
- * @param parambytes 原byte数组
- * @return 处理后剩余部分的byte数组
- */
- private static void splitInputStreamByte(byte[] parambytes) {
- if(parambytes != null){
- if(parambytes.length > 4){
- byte[] head = new byte[4]; //单包长度
- System.arraycopy(parambytes, 0, head, 0, 4);
- int bodyLength = ByteArrayUtil.getint(head);
- if(bodyLength <= parambytes.length-4){
- final byte[] body = new byte[bodyLength];
- System.arraycopy(parambytes, 4, body, 0, bodyLength);
- ThreadPool.execute(new Runnable(){
- public void run(){
- byte[] processDatas = body;
- try{
- System.out.println(IOUtils.toString(processDatas, "UTF-8").trim());
- }catch(IOException e){
- logger.error(e.getMessage(), e);
- }
- }
- });
- int resultLen = parambytes.length-4-bodyLength;
- if(resultLen == 0){
- splitInputStreamByte(null);
- }else{
- byte[] resultbytes = new byte[resultLen];
- System.arraycopy(parambytes, 4+bodyLength, resultbytes, 0, resultLen);
- splitInputStreamByte(resultbytes);
- }
- }else{
- tmpbytes.clear();
- tmpbytes.add(parambytes);
- }
- }else{
- tmpbytes.clear();
- tmpbytes.add(parambytes);
- }
- }
- }
- public static void openflag(){
- businessflag = true;
- }
- public static void closeflag(){
- businessflag = false;
- }
- }
TestTcpSocket.java代码:
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import com.shihuan.dragonkeeper.common.utils.ByteArrayUtil;
- import com.shihuan.dragonkeeper.global.ConfigFile;
- public class TestTcpSocket implements Runnable{
- private Socket socketClient = null;
- public void run(){
- String serverip = "192.168.1.10";
- int port = 19990;
- try{
- while(true){
- System.out.println("SocketClient start......");
- String mystr = "hello everyone!";
- socketClient = new Socket(serverip, port);
- OutputStream os = socketClient.getOutputStream();
- byte[] head = ByteArrayUtil.int2byte(mystr.length());
- byte[] body = mystr.getBytes();
- byte[] total = ByteArrayUtil.byteMerge(head, body);
- os.write(total);
- os.flush();
- os.close();
- Thread.sleep(1000);
- System.out.println("SocketClient end......");
- }
- }catch(Exception e){
- logger.error(e.getMessage(), e);
- }
- }
- public static void main(String[] args){
- Thread t = new Thread(new TestTcpSocket());
- t.start();
- }
- }
下面写ByteArrayUtil.java代码:
- package com.shihuan.dragonkeeper.common.utils;
- public class ByteArrayUtil {
- /**
- * 将int型的数据类型转换成byte[]类型
- */
- public static final byte[] int2byte(int paramInt){
- byte[] resultByte = new byte[4];
- resultByte[3] = ((byte)(paramInt & 0xFF));
- resultByte[2] = ((byte)(paramInt >>> 8 & 0xFF));
- resultByte[1] = ((byte)(paramInt >>> 16 & 0xFF));
- resultByte[0] = ((byte)(paramInt >>> 24 & 0xFF));
- return resultByte;
- }
- /**
- * 将byte型的数据类型转换成int类型
- */
- public static final int getint(byte[] paramArrayOfByte){
- int result = (paramArrayOfByte[0] & 0xFF) << 24 | (paramArrayOfByte[1] & 0xFF) << 16 | (paramArrayOfByte[2] & 0xFF) << 8 | paramArrayOfByte[3] & 0xFF;
- return result;
- }
- /**
- * 合并两个byte数组到一个byte数组中
- */
- public static byte[] byteMerge(byte[] byte1, byte[] byte2){
- byte[] result = new byte[byte1.length+byte2.length];
- System.arraycopy(byte1, 0, result, 0, byte1.length);
- System.arraycopy(byte2, 0, result, byte1.length, byte2.length);
- return result;
- }
- }
http://blog.csdn.net/defonds/article/details/8782785
Java Socket长连接示例代码的更多相关文章
- java socket 长连接 短连接
长连接 是一旦一个客户端登陆上服务器,其与服务器之间的连接就不关闭,不管他们之间进行了多少次交易,直到客户端退出登陆或网络出现故障.这种技术在联机交易系统实现有利于提高效率. 短连接是客户端每发一个请 ...
- Java socket长连接代码实现
服务器端程序: import java.io.*; import java.net.*; import java.util.*; public class ChatServer { boolean s ...
- java Socket 长连接 心跳包 客户端 信息收发 demo
今天写了个socket的测试小程序,代码如下 import java.io.IOException; import java.io.InputStream; import java.io.Output ...
- 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...
- android端 socket长连接 架构
看过包建强的<App研发录>之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及socket相 ...
- 【Socket】关于socket长连接的心跳包
TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive) 据网络搜索到的资料解释如下 内网机器如果不主动向外发 ...
- 基于心跳的socket长连接
http://coach.iteye.com/blog/2024444 基于心跳的socket长连接 博客分类: http socket 案例: 心跳: socket模拟网页的报文连接某个网站,创建t ...
- 基于netty框架的socket长连接负载均衡解决方案
socket通讯的单机瓶颈 物联网的项目socket使用方式有两种: 短连接的socket请求 维持socket长连接的请求 对于socket短链接来说就好比是http请求,请求服务器,服务器返回数据 ...
- Socket 长连接 短连接 心跳 JAVA SOCKET编程
简单解释就是: 短连接:建立连接,发送数据包.关闭连接 长连接:建立连接.发送数据包,发送心跳包,发送数据包,发送心跳包.发送心跳包. ..... 所以又频繁的数据收发的话.短连接会频繁创建TCP连接 ...
随机推荐
- SQL Server数据库性能优化之SQL语句篇【转】
SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...
- Android中的动画效果
动画的种类 透明动画alphaAnimation 在代码中配置动画: findViewById(R.id.btnAnimMe).setOnClickListener(new View.OnClickL ...
- Apriori on MapReduce
Apiroi算法在Hadoop MapReduce上的实现 输入格式: 一行为一个Bucket 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 34 36 38 ...
- web学习之servlet
1)web服务软件作用: 把本地资源共享给外部访问 2)tomcat服务器基本操作 : 启动: %tomcat%/bin/startup.bat 关闭: %tomcat%/bin/shutdown. ...
- Oracle Merge into 详细介绍
Oracle Merge into 详细介绍 /*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查 ...
- 浅谈Extjs radiogroup change事件与items下的checked属性
在使用Extjs制作crud时,由于添加和修改界面的高度相似,使用了相同的row字段. 在角色字段中使用了change监听事件,用于动态的无效化权限分配字段,因为权限分配界面默认没有隐藏,设定了che ...
- 谈谈eclipse使用技巧
俗话说的好啊,“工于利启事,必先善其器”,如果说你的编程功底是一个枪法的话,那么强大的eclipse就是android战士们最好的武器. 这里,我们来总结eclipse的使用技巧,从而使我们的编程达到 ...
- c/c++常用网址
个人主页Dennis Ritchie's home pagehttp://cm.bell-labs.com/cm/cs/who/dmr/index.html Brian Kernighan's hom ...
- C++数据类型和变量类型。
数据类型 数字是自由的[不只属于某个类型]!但是它可以有不同的身份!int.char.float.double等身份.它以不同的身份[存储规则]存储在内存的某个位置内部! 变量类型 内存编号是不会变的 ...
- ANDROID : java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.encodeBase64String in android
Andriod系统包中现在已经自带加密函数,如果用apache的codec包则会报以上错误,用android.util.Base64以下方法代替org.apache.commons.codec.bin ...