`
Franciswmf
  • 浏览: 797333 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

socket通信例子_服务端写客户端读多线程写法

 
阅读更多
1、主程序
/**
	 * 主程序启动入口
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		ctx = new ClassPathXmlApplicationContext(APPLICATION_XML_FILE);
		ctx.start();
		//
		SingletonMessagePush instance=SingletonMessagePush.getInstance();//单例服务类
		try {
			ServerSocket serverSocket=new ServerSocket(getMessagePushPort());//serverSocket,只负责监听客户端连接,一旦连接成功,服务端会新建一个socket负责与客户端通信
			while(true){//不断监听客户端连接
				Socket socket = serverSocket.accept();//返回一个客户端的Socket对象实例
				//
				System.out.println("【发现客户端连接>>>>>>】");
				if(null!=socket){
					CopyOnWriteArrayList<Socket> oldList=instance.getSocket();
	        		for (Socket so : oldList) {
	        			if(so.isConnected()==false||so.isClosed()==true){
	        				instance.getSocket().remove(so);//移除
	        				System.out.println(so.getInetAddress()+"从socket客户端集合移除。");
	        			}
	        		}
	        		if(socket.isConnected()==true&&socket.isClosed()==false){
		        		instance.getSocket().add(socket);//添加客户端socket
						System.out.println("添加客户端:"+socket.getInetAddress()+",当前有效客户端总数:"+instance.getSocket().size());
	        		}
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("主程序启动时服务端socket异常");
		}
	}


2、推送消息单例类
package com.vxichina.cluster.persistence.core;

import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* @author mingfeng.wang
* @date 2016年3月15日 
* @time 上午10:54:18
* 向录屏程序推送消息的类
*/
public class SingletonMessagePush {
	//有效客户端socket连接集合
	private CopyOnWriteArrayList<Socket> socket=new CopyOnWriteArrayList<Socket>();
	//线程池
	private ExecutorService threadPool=Executors.newCachedThreadPool();
	//private构造函数
	private SingletonMessagePush(){
		
	}
	private static SingletonMessagePush instance;
	//对外访问方法
	public static SingletonMessagePush getInstance(){
		if(null==instance){
			instance=new SingletonMessagePush();
		}
		return instance;
	}
	/**
	 * 推送消息的主方法
	 * @param dataStr
	 */
	public void doMain(String dataStr){
		try {
	         if(null!=dataStr&&!"".equals(dataStr)){
	        	if(null!=socket&&socket.size()>0){
	        		//#s 给所有有效连接的客户端推送消息
	        		for (Socket sc : this.getSocket()) {
	        			final String message=dataStr;
	        			final Socket clientSocket=sc;
	        			if(sc.isConnected()==true&&sc.isClosed()==false){
	        				//new Thread(new Task(sc,dataStr)).start();//多线程
	        				Thread.sleep(0);
	        				//线程池方式
	        				threadPool.execute(new Runnable() {
								@Override
								public void run() {
									try {
										System.out.println("当前线程name="+Thread.currentThread().getName()+",  id="+Thread.currentThread().getId());
										// 服务端写数据
										Writer writer = new OutputStreamWriter(clientSocket.getOutputStream());
										writer.write(message);
										writer.flush();
										System.out.println("成功给客户端"+clientSocket.getInetAddress()+"推送消息。消息内容:\n"+message);
										//writer.close();//不能关闭,关闭会导致客户端close一段时间
									}catch (Exception e) {
										System.out.println("给客户端"+clientSocket.getInetAddress()+"推送消息异常。");
									}
								}
							});
	        			}
					}
	        		//#e
				}else{
					System.out.println("暂无客户端连接。");
				}
	         }
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("doMain推送消息异常。");
		}
	}
	
	
	public CopyOnWriteArrayList<Socket> getSocket() {
		return socket;
	}
	public void setSocket(CopyOnWriteArrayList<Socket> socket) {
		this.socket = socket;
	}


}


3、模拟客户端访问
public class ClientSocketTest {

	public static void main(String[] args) {
		String host="192.68.19.64";//自定义
		int port=9080;
		try {
			Socket client = new Socket(host, port);
			while(true){
				System.out.println("【>>>>>>客户端正在监听>>>>>>】,isConnected="+client.isConnected()+",isClosed="+client.isClosed());
				// 客户端读数据
				Reader reader = new InputStreamReader(client.getInputStream());
				char chars[] = new char[64];
				int len;
				StringBuffer sb = new StringBuffer();
				while ((len = reader.read(chars)) != -1) {
					sb.append(new String(chars, 0, len));
				}
				System.out.println("客户端读数据结束。" );
				reader.close();
				//client.close();
			
			}
		}catch(java.net.SocketException e){
			if(e.getMessage().equals("Connection reset")){
				System.out.println("连接被重置,服务端已关闭。");
			}
		}catch (Exception e) {
			e.printStackTrace();
			System.out.println("客户端其它异常。");
		}
	}
}


===============================================================================
1、服务端监听端口
private static final String appConfigFile = "/app-config.properties";
public static void main(String[] args) {
		SingletonServerSocket singletonServerSocket=SingletonServerSocket.getInstance();
		try {
			//System.out.println("端口:"+getMessagePushPort());
			ServerSocket serverSocket=new ServerSocket(getMessagePushPort());
			singletonServerSocket.setServerSocket(serverSocket);//serverSocket
			while(true){
				Socket socket = serverSocket.accept();//监听,接受客户端连接
				if(null!=socket){
					singletonServerSocket.setSocket(socket);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 从Properties文件中获取推送信息需要监听的socket通信端口
	 * @return
	 */
	public static int getMessagePushPort(){
		int port=0;
		Properties properties = new Properties();
		try {
			properties.load(Object.class.getResourceAsStream(appConfigFile));
		} catch (IOException e) {
			e.printStackTrace();
		}
	    port=Integer.valueOf(properties.getProperty("messagePushPort").trim());
		return port;
	}


2、调用
SingletonServerSocket singletonServerSocket=SingletonServerSocket.getInstance();//单例类
//推送socket消息到客户端
singletonServerSocket.doMain(str.toString());


3、SingletonServerSocket 单例类-服务端写数据
public class SingletonServerSocket {
	private ServerSocket serverSocket;
	private Socket socket;
	//private构造函数
	private SingletonServerSocket(){
		
	}
	private static SingletonServerSocket instance;
	//对外访问方法
	public static SingletonServerSocket getInstance(){
		if(null==instance){
			instance=new SingletonServerSocket();
		}
		return instance;
	}
	/**
	 * 推送消息的主方法
	 * @param dataStr
	 */
	public void doMain(String dataStr){
		try {
	         if(null!=dataStr&&!"".equals(dataStr)){
	        	 if(null!=socket){
	        		 	new Thread(new Task(socket,dataStr)).start();//多线程
					}else{
						System.out.println("暂无客户端连接,无法完成写操作。");
					}
	         }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	 /**
	  * 用来处理socket请求的多线程
	  * 
	  *
	  */
	static class Task implements Runnable {

		private Socket socket2;
		private String data;

		public Task(Socket socket, String data) {
			this.socket2 = socket;
			this.data = data;
		}

		public void run() {
			try {
				handleSocket();// 处理客户端socket
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		/**
		 * 跟客户端Socket进行通信
		 * 
		 */
		private void handleSocket(){
			try {
				// 服务端写数据
				Writer writer = new OutputStreamWriter(socket2.getOutputStream());
				writer.write(data);
				System.out.println("服务端写数据:" + data);
				writer.flush();
				//writer.close();
			} catch (java.net.SocketException e) {
				System.out.println("无法找到写数据的客户端!");
			} catch (Exception e) {
				System.out.println("服务端写数据错误!");
			}
			// socket2.close();//服务端socket,不能关闭
		}
	}
	public ServerSocket getServerSocket() {
		return serverSocket;
	}
	public void setServerSocket(ServerSocket serverSocket) {
		this.serverSocket = serverSocket;
	}
	public Socket getSocket() {
		return socket;
	}
	public void setSocket(Socket socket) {
		this.socket = socket;
	}

}

4、客户端读数据
public class ClientSocket {

	public static void main(String[] args) {
		String host="192........";
		int port=9099;
		try {
			Socket client = new Socket(host, port);
			while(true){
				System.out.println("client request...");
				
				if(client.isClosed()){
					client = new Socket(host, port);
				}
				// 客户端读数据
				Reader reader = new InputStreamReader(client.getInputStream());
				char chars[] = new char[64];
				int len;
				StringBuffer sb = new StringBuffer();
				while ((len = reader.read(chars)) != -1) {
					sb.append(new String(chars, 0, len));
				}
				System.out.println("客户端读数据:" + sb);
				reader.close();
				client.close();
			
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
分享到:
评论

相关推荐

    Linux之select多socket范例

    本文将深入探讨如何在Linux环境下利用`select`实现多socket通信,特别是针对UDP协议的服务端实例。 首先,`select`函数是多路复用I/O模型的一种,它允许程序同时监控多个文件描述符(包括socket),等待它们就绪...

    Python实现socket非阻塞通讯功能示例

    以上内容总结了使用Python实现socket非阻塞通讯功能的原理和技巧,包括单进程基本写法、多线程实现、服务端和客户端的具体编程方法等。对于想要深入学习Python网络编程的朋友,文中推荐了多个专题教程,如《Python ...

    linux c 语言编写的ftp服务器程序

    通过以上介绍,我们可以看出这个项目涵盖了网络编程、文件系统操作、用户权限管理、多线程编程以及跨平台GUI设计等多个方面,对于提升Linux系统和C语言的实践能力具有很高的价值。同时,它也展示了如何将低级系统...

    java_len.zip_java len

    7. **网络编程**:如Socket通信,客户端和服务端的编程实现。 8. **反射机制**:在运行时动态获取类信息并操作对象的能力,常用于插件化开发和自动化测试。 9. **JDBC**:Java数据库连接,用于访问和操作数据库。 ...

    Java程序设计技巧1001例

    8. **网络编程**:Java的Socket编程允许创建客户端和服务端应用,理解TCP和UDP协议,以及Socket和ServerSocket类的使用。 9. **反射机制**:反射机制允许程序在运行时获取类的信息并动态调用方法,这是许多高级功能...

    java期末复习13题及答案

    - Socket编程:客户端和服务端通过Socket进行通信。 - URL和URLConnection:用于访问网络资源。 9. **反射机制**: - Class类:代表运行时的类信息,可以动态获取类的属性和方法。 - 构造器和方法的反射调用:...

    Python中asyncore的用法实例

    import asyncore,socket ######################################################################## class AsyncGet(asyncore.dispatcher): """ the defined class """ #----------------------------------...

    100个C#程序实例(含代码,截图,.cs文件)

    15. **网络编程**:掌握Socket编程,了解HTTP协议,创建客户端和服务端的网络通信。 每个实例都配有代码和截图,这有助于你直观地理解代码运行过程和结果。同时,.cs文件是源代码文件,可以直接在Visual Studio等...

    java 面试题,包含内容比较全

    - **Socket编程**:如何创建TCP和UDP套接字,进行客户端和服务器间的通信。 - **HTTP协议**:理解HTTP的基本概念和工作原理,以及使用Java实现简单的HTTP客户端和服务端。 9. **反射与注解** - **反射**:通过...

    新考试

    - **Socket编程**:实现客户端和服务端的通信,基于TCP/IP协议。 - **URL和URLConnection**:用于访问网络资源。 6. **多线程** - **Thread类**:创建并控制线程,通过`start()`方法启动执行。 - **Runnable...

Global site tag (gtag.js) - Google Analytics