`

Socket长连接和心跳

 
阅读更多

       LZ一直没有涉猎过长连接,原因不过多解释,懒可能是其中一个理由。突然有一天觉着是个遗憾,于是自己顺手用Socket搞了一个,包括长连接必须有的心跳机制,和对象的传递,当然用到了JAVA序列化,传递的对象必须实现java.io.Serializable接口。

       客户端:

package com.feng.test.longconnection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

/**
 * 
 * @author songfeng
 * @version 1.0
 * @since 2015-10-14
 * @category com.feng.test.longconnection
 *
 */
public class Client
{
	private Socket socket;
	
	private String ip;
	
	private int port;
	
	private String id;
	
	ObjectOutputStream oos;
	
	BufferedReader br;
	
	public Client(String ip, int port,String id)
	{
		try
		{
			this.ip = ip;
			this.port = port;
			this.id = id;
			this.socket = new Socket(ip, port);
			this.socket.setKeepAlive(true);
			oos = new ObjectOutputStream(socket.getOutputStream());
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			new Thread(new heartThread()).start();
			new Thread(new MsgThread()).start();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void sendMsg(Object content)
	{
		try
		{
			oos.writeObject(content);
			oos.flush();
		}
		catch (Exception e)
		{
			closeSocket();
		}
	}
	
	public void closeSocket()
	{
		try
		{
			socket.close();
			oos.close();
			br.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	class heartThread implements Runnable
	{
		@Override
		public void run()
		{
			while(true)
			{
				try
				{
					Thread.sleep(1000);
					long time = System.currentTimeMillis();
					//System.out.println("client send:" + time);
					sendMsg("Client" + id + " send:" + time);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	
	class MsgThread implements Runnable
	{
		@Override
		public void run()
		{
			String str = null;
			while(true)
			{
				try
				{
					if(socket.getInputStream().available() > 0)
					{
						while((str = br.readLine()) != null)
						{
							System.out.println(str);
						}
					}
				}
				catch (IOException e)
				{
					closeSocket();
				}
			}
		}
	}
	
	public static void main(String[] args)
	{
		Client client1 = new Client("127.0.0.1", 55555, "1");
		client1.sendMsg(new Pojo("songfeng", 26, new ArrayList<String>()));
		try
		{
			Thread.sleep(500);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		Client client2 = new Client("127.0.0.1", 55555, "2");
	}
}

        服务端:

package com.feng.test.longconnection;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
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;

/**
 * 
 * @author songfeng
 * @version 1.0
 * @since 2015-10-14
 * @category com.feng.test.longconnection
 *
 */
public class Server
{
	private ServerSocket serverSocket;
	
	private Socket socket;
	
	private int port;
	
	static List<Socket> list = new ArrayList<Socket>();
	
	ExecutorService exec; 
	
	public Server(int port)
	{
		try
		{
			this.port = port;
			this.serverSocket = new ServerSocket(port);
			
			//线程池管理客户端线程。
			exec = Executors.newCachedThreadPool();
			while (true)
			{
				socket = serverSocket.accept();
				list.add(socket);
				exec.execute(new MsgThread(socket));
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public void closeSocket()
	{
		try
		{
			for(Socket s : list)
			{
				s.close();
			}
			serverSocket.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	class MsgThread implements Runnable
	{
		private Socket socket;
		
		private long lastHeatTime = System.currentTimeMillis();
		
		public MsgThread(Socket socket)
		{
			this.socket = socket;
		}
		
		@Override
		public void run()
		{
			ObjectInputStream oin = null;
			PrintWriter pw = null;
			String str = null;
			try
			{
				oin = new ObjectInputStream(this.socket.getInputStream());
				pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream())));
				while(true)
				{
					if(!socket.isConnected())
					{
						break;
					}
					if(socket.getInputStream().available() > 0)
					{
						if(System.currentTimeMillis() - lastHeatTime > 5000)
						{
							break;
						}
						
						oin.readFields();
						Object object = oin.readObject();
						if(object instanceof String)
						{
							lastHeatTime = System.currentTimeMillis();
							long time = System.currentTimeMillis();
							pw.println(object + ",Server back:" + time);
							pw.flush();
						}
						else if(object instanceof Pojo)
						{
							pw.println(object + ",Server back:" + ((Pojo)object).getName());
							pw.flush();
						}
					}
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				try
				{
					this.socket.close();
					list.remove(socket);
					if(oin != null)
					{
						oin.close();
					}
					pw.close();
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args)
	{
		Server server = new Server(55555);
	}
}

        数据类:

package com.feng.test.longconnection;

import java.io.Serializable;
import java.util.List;

/**
 * 
 * @author songfeng
 * @version 1.0
 * @since 2015-10-16
 * @category com.feng.test.longconnection
 *
 */
public class Pojo implements Serializable
{

	/**
	 * 序列化
	 */
	private static final long serialVersionUID = -8868529619983791261L;
	
	private String name;
	
	private int age;
	
	private List<String> likeThing;
	
	public Pojo(String name, int age, List<String> likeThing)
	{
		super();
		this.name = name;
		this.age = age;
		this.likeThing = likeThing;
	}

	public String getName()
	{
		return name;
	}
	
	public void setName(String name)
	{
		this.name = name;
	}

	public int getAge()
	{
		return age;
	}
	
	public void setAge(int age)
	{
		this.age = age;
	}
	
	public List<String> getLikeThing()
	{
		return likeThing;
	}
	
	public void setLikeThing(List<String> likeThing)
	{
		this.likeThing = likeThing;
	}
}

 

 

1
0
分享到:
评论

相关推荐

    Android的socket长连接(心跳检测)

    - 这个文件可能是一个服务(Service),负责接收和处理来自客户端的Socket连接和心跳包。 - 服务启动后,监听指定端口,当有新的Socket连接请求时,创建线程处理客户端的输入输出流,同时处理心跳检测。 6. **...

    Socket长连接+心跳包+发送读取

    以下是Socket长连接、心跳包和数据发送读取的关键知识点: 1. **TCP连接**:Socket基于传输层的TCP协议,提供可靠的双向通信。TCP保证了数据的顺序和完整性,通过三次握手建立连接,四次挥手断开连接。 2. **...

    Android-Socket长连接通信心跳包消息回调Java服务端

    通过分析和学习这个项目,你可以更直观地了解上述知识点的实现方式,包括如何创建Socket连接、实现心跳包、处理消息回调以及服务端的多线程处理等。 总结,实现“Android-Socket长连接通信心跳包消息回调Java服务端...

    Java实现Socket长连接和短连接

    Socket连接分为两种类型:长连接和短连接。这两种连接方式各有特点,适用于不同的应用场景。 **1. 短连接(Short Connection)** 短连接通常用于一次性、非持久性的通信,如HTTP协议就是典型的短连接。在短连接中...

    Socket长连接心跳

    Socket长连接心跳是网络通信中保持连接活性的重要技术,尤其在移动端如安卓应用中更为常见。Socket,全称是“套接字”,是网络编程的基本接口,它允许应用程序通过网络发送和接收数据。心跳机制则是确保连接持续有效...

    TCP长连接Socket心跳收发消息

    本篇文章将深入探讨TCP长连接Socket以及心跳收发消息的原理和实现方法。 首先,TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过三次握手建立连接,并在连接建立后可以进行双向数据传输。TCP连接...

    socket 长连接 多线程 心跳包 包头包体

    socket 长连接 简单例子,适合初学的朋友,里面有多线程 实现的,包括心跳包,数据分为两部分传送,首先双方约定用一个4字节的数组告诉对方要传送数据的长度,然后在写入数据,这样长连接的时候,双方可以知道对方...

    c# Socket长连接 短链接 自己封装 通讯

    标题“c# Socket长连接 短链接 自己封装 通讯”揭示了我们将讨论的主题:如何使用C#实现Socket的长连接和短连接,并自定义通信协议。这里的关键点包括: 1. **Socket基础**:Socket是网络通信中的一个抽象概念,它...

    Socket长连接demo

    在TCP/IP协议族中,Socket分为两种类型:短连接(Short-lived Connection)和长连接(Long-lived Connection)。短连接通常用于一次性传输数据,如HTTP请求;而长连接则适合于保持连接状态,以便进行多次数据交互,...

    Socket心跳连接_java

    1. **建立Socket连接**:客户端使用`Socket`类的构造函数,指定服务器的IP地址和端口号,建立到服务器的连接。 2. **心跳包设计**:定义心跳包的格式,例如可以是一个简单的JSON对象,包含时间戳和"ping"或"pong"的...

    C# socket异步长连接

    在C#中,System.Net.Sockets命名空间提供了Socket类,用于创建和管理socket连接。 在“异步”方面,C#的Socket支持异步操作模式,这意味着你可以启动一个网络操作(如连接、接收或发送数据),然后继续执行其他任务...

    java socket 长连接实例

    "Java Socket 长连接实例"是关于如何实现一个持久连接的服务器和客户端程序的示例,这种连接能够保持开放,直到一方明确地关闭它。这在需要频繁通信或者需要长时间保持连接状态的应用场景中非常有用,比如聊天应用、...

    Socket长连接异常处理

    长连接需要至少两个线程,一个用于接收数据,一个用于发送心跳和写数据。短连接不需要发送心跳的线程。如果是服务器端,还需要一个专门的线程负责进行连接请求的监听。 Socket 长连接异常处理需要注意以上这些问题...

    socket 长连接实例

    - **关闭连接**:通信完成后,使用`close()`函数关闭Socket连接。 3. **长连接的维护**: - 在长连接中,服务器和客户端不会在每次数据交换后立即关闭连接,而是会维持一段时间的空闲状态,等待下一次数据传输。 ...

    socket长连接demo

    总结起来,Java Socket编程中的长连接实现涉及TCP连接的创建、数据交换、心跳机制以及资源的管理和关闭。理解和掌握这些知识点对于开发高效、可靠的网络应用至关重要。在实际工作中,还需要考虑异常处理、线程安全...

    android客户端加服务端的socket长连接

    4. 长连接需要保持Socket连接状态,通常会设置心跳机制,定期发送心跳包以检查连接是否正常。 三、客户端对服务器发送消息 1. 客户端通过Socket的OutputStream将要发送的消息编码成字节流,然后写入到输出流。 2. ...

    进程间负载,基于socket长连接

    5. **性能优化**:保持长连接需要处理心跳机制、超时检测、重连策略等问题,以确保连接的稳定性和效率。同时,还需关注内存管理、并发控制、错误处理等,以防止资源泄露和系统崩溃。 6. **安全与可靠性**:使用...

    socket长连接

    "socket长连接"是指在客户端和服务端之间建立的一种持久性的连接,它允许双方在连接保持打开状态下进行多次数据交换,而不必每次通信都进行连接的建立和断开。这种模式在需要频繁交互或实时性要求较高的场景中尤为...

    Androidsocket通信加长连接(有心跳检测)

    在Android中,我们可以使用java.net.Socket类来创建和管理Socket连接。 心跳检测机制是为了确保连接的稳定性和及时发现网络问题。在长连接中,由于网络环境的不稳定,可能会出现连接断开但双方并未察觉的情况。心跳...

    Android Socket连接(心跳检测,断线重连,状态监测等)

    Android Socket连接,包含心跳检测,断线重连,数据发送等等 博客地址:http://blog.csdn.net/yuzhiqiang_1993/article/details/78094909

Global site tag (gtag.js) - Google Analytics