欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Socket长连接和心跳 博客分类: SocketJ2SE  

程序员文章站 2024-03-23 08:48:28
...

       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;
	}
}