`
cuisuqiang
  • 浏览: 3935483 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3650148
社区版块
存档分类
最新评论

一个Socket连接管理器

阅读更多

为了方便开发人员使用,我在闲暇之余写了一个简单的Socket连接管理的处理程序,程序简单仅供参考!

其他更多精彩,请你访问我的博客:http://cuisuqiang.iteye.com/

 

处理机说明:

读取配置文件,根据配置文件信息保持一个连接配置变量集合。

根据连接变量集合初始化相应的连接。

启动一个线程,处理检查连接的有效性,处理方法是发送心跳包,如发现不能使用的连接,则设置该连接为占用,并启动一个线程去不断的初始化该连接。

用户使用接口根据名称去获得连接,如果是保持的连接则直接从连接集合获取,并检查有效性。如果是不用保持的,则去创建一个连接返回。

备注:如果返回了空的信息,则说明没有正常的连接可以返回,你可以尝试不断的获取。

点击连接到我的博客查看更多内容

 

下面来看看代码:

首先创建一个实体对象,对应配置信息

package com.socket;
/**
 * @说明 连接的公共属性
 * @author cuisuqiang
 * @version 1.0
 * @since
 */
public class SocketEntity {
	/**
	 * 连接的名字,以名字作为Key
	 */
	private String name;
	/**
	 * 连接的IP
	 */
	private String ip;
	/**
	 * 连接的端口
	 */
	private int port;
	/**
	 * 是否保持连接
	 */
	private boolean keepConn;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}	
	public int getPort() {
		return port;
	}
	public void setPort(int port) {
		this.port = port;
	}
	public boolean isKeepConn() {
		return keepConn;
	}
	public void setKeepConn(boolean keepConn) {
		this.keepConn = keepConn;
	}
}

 

创建配置文件socket.properties

socket1_isKeep属性相当于Spring中的单例还是每次创建

 

 

# @author cuisuqiang

socket1=socket1
socket1_ip=127.0.0.1
socket1_port=8001
socket1_isKeep=1

socket2=socket2
socket2_ip=127.0.0.1
socket2_port=8001
socket2_isKeep=0

# 连接的数量,一定要和实际配置的数量匹配
socketConnCount=2
# 公共的检测间隔 秒
commonCheckTime=5

 

然后初始化配置信息和连接,同时该类中有静态变量来保持连接对象

package com.socket;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @说明 变量保持
 * @author cuisuqiang
 * @version 1.0
 * @since
 */
public class SocketKeep {
	private static Log logger = LogFactory.getLog(SocketKeep.class);
	/**
	 * 配置信息加载
	 */
	public static List<SocketEntity> socketEntityList = new ArrayList<SocketEntity>();
	/**
	 * 连接对象保持,只保持需要系统保持的连接
	 */
	public static Map<String, SocketCui> socketMap = new LinkedHashMap<String, SocketCui>();
	/**
	 * 连接对象是否锁定 1:锁定,其他未锁定
	 */
	public static Map<String, String> socketIsLock = new LinkedHashMap<String, String>();
	/**
	 * 共用连接检测间隔
	 */
	public static int commonCheckTime = 2;
	/**
	 * 连接的数量,一定要和实际配置的数量匹配
	 */
	public static int socketConnCount = 0;	
	public static ExecutorService executorService = null;// 线程池
	/**
	 * 初始化所有连接信息
	 */
	public static void initSocketKeep() {
		Properties properties = null;
		try {
			properties = new Properties();
			properties.load(SocketKeep.class.getClassLoader().getResourceAsStream("socket.properties"));
			logger.warn("加载socket.properties文件成功!");
		} catch (Exception e) {
			logger.error("加载socket.properties文件失败!", e);
			properties = null;
		}
		if (null != properties) {
			try {
				commonCheckTime = Integer.parseInt(properties.getProperty("commonCheckTime"));
				socketConnCount = Integer.parseInt(properties.getProperty("socketConnCount"));
				executorService = Executors.newFixedThreadPool(socketConnCount + 1);
			} catch (Exception e) {
				executorService = Executors.newFixedThreadPool(1);
				logger.error("解析共用信息时错误!", e);
				// 系统忽略这两个属性的加载异常
			}
			SocketEntity socketEntity = null;
			for (int i = 1; i <= socketConnCount; i++) {
				String name = properties.getProperty("socket" + i);
				if(null != name){
					socketEntity = new SocketEntity();
					String ip = properties.getProperty("socket" + i + "_ip");
					String port = properties.getProperty("socket" + i + "_port");
					String isKeep = properties.getProperty("socket" + i + "_isKeep");
					
					socketEntity.setName(name);
					socketEntity.setIp(ip);
					socketEntity.setPort(Integer.parseInt(port));
					boolean keepConn = false;
					if(null != isKeep && "1".equals(isKeep)){
						keepConn = true;
					}
					socketEntity.setKeepConn(keepConn);	
					socketEntityList.add(socketEntity);
				}
			}
		}
		logger.warn("加载Socket连接配置信息结束!");		
		logger.warn("开始初始化Socket连接!");
		SocketCui socket = null;
		for(SocketEntity socketEntity : socketEntityList){
			if(null != socketEntity && socketEntity.isKeepConn()){
				try {
					socket = new SocketCui(socketEntity.getIp(),socketEntity.getPort());
					socket.setSoTimeout(0);
					socket.setKeepAlive(true);
					socket.setName(socketEntity.getName());
				} catch (Exception e) {
					logger.error("初始化某个连接时错误!错误的连接将放弃!资源名称:" + socketEntity.getName(), e);
					socket = null;
				}
				if(null != socket){
					socketMap.put(socketEntity.getName(), socket);
				}else{
					socketMap.put(socketEntity.getName(), new SocketCui());					
				}
				socketIsLock.put(socketEntity.getName(), "0");
			}
		}		
		// 开始执行检查
		executorService.execute(new CheckThread());
		logger.warn("初始化Socket连接结束!");
	}
}

 

启动的线程是用于检查连接的

package com.socket;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @说明 轮询检测某个连接当前是否可用
 * @author cuisuqiang
 * @version 1.0
 * @since 当遇到一个错误的连接,将会启动重连,同时挂起该连接的使用
 */
public class CheckThread  implements Runnable {
	private static Log logger = LogFactory.getLog(CheckThread.class);	
	public void run() {
		while(true){
			SocketCui socket = null;
			for(SocketEntity socketEntity : SocketKeep.socketEntityList){
				if(null != socketEntity && socketEntity.isKeepConn()){
					String isLock = SocketKeep.socketIsLock.get(socketEntity.getName());
					// 如果当前未被使用
					if(!"1".equals(isLock)){
						// 锁定引用
						SocketKeep.socketIsLock.put(socketEntity.getName(), "1");
						socket = SocketKeep.socketMap.get(socketEntity.getName());
						try {
							// 发送一个心跳包
							socket.sendUrgentData(0xFF);
							// 释放资源
							SocketKeep.socketIsLock.put(socketEntity.getName(), "0");
						} catch (Exception e) {
							logger.error("检查连接时异常!启动重连!资源名称:" + socketEntity.getName(), e);
							// 如果异常,应该建立一个线程去初始化该连接
							InitSocket initS = new InitSocket(socketEntity.getName());
							new Thread(initS).start();
						}
					}
				}
			}
			// 执行间隔
			try {
				logger.error("本次检测结束!");
				Thread.sleep(SocketKeep.commonCheckTime * 1000);
			} catch (Exception e) {
			}			
		}
	}
}

 

当检查线程发现无效的连接时会启动新的线程初始化该连接

package com.socket;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @说明 负责初始化失效的连接
 * @author cuisuqiang
 * @version 1.0
 * @since
 */
public class InitSocket implements Runnable{	
	private static Log logger = LogFactory.getLog(InitSocket.class);	
	/**
	 * 是否有某个连接的配置信息,只有有配置信息才能建立连接
	 */
	private static boolean isHave = false;	
	private SocketEntity socketEntity = null;	
	private String name;	
	public InitSocket(String name){
		this.name = name;
		// 检测是否有某个连接的配置信息
		for(SocketEntity socketEntity : SocketKeep.socketEntityList){
			if(null != socketEntity && socketEntity.isKeepConn()){
				if(socketEntity.getName().equals(name)){
					this.setSocketEntity(socketEntity);
					isHave = true;
				}
			}
		}
	}
	public void run() {
		boolean isError = true;
		SocketCui socket = null;
		if(isHave){
			while(isError){
				try {
					socket = new SocketCui(this.getSocketEntity().getIp(),this.getSocketEntity().getPort());
					socket.setSoTimeout(0);
					socket.setKeepAlive(true);
					socket.setName(this.name);
					// 发送一个心跳包
					socket.sendUrgentData(0xFF);						
				} catch (Exception e) {
					logger.error("建立资源连接时错误!资源:" + this.name, e);
					socket = null;
				}
				if(null != socket){
					SocketKeep.socketMap.put(this.getSocketEntity().getName(), socket);
					// 设置连接当前可用
					SocketKeep.socketIsLock.put(this.getSocketEntity().getName(), "0");
					logger.warn("建立资源连接成功!资源名称:" + this.name);
					isError = false;
				}
				try {
					Thread.sleep(2 * 1000);
				} catch (Exception e) {
				}
				
			}
		}else{
			logger.error("没有发现指定资源的配置信息!资源名称:" + this.name);
		}
		logger.warn("初始化资源执行结束!资源名称:" + this.name);
	}
	public SocketEntity getSocketEntity() {
		return socketEntity;
	}
	public void setSocketEntity(SocketEntity socketEntity) {
		this.socketEntity = socketEntity;
	}
}

 

同时注意,用户在使用连接后会调用关闭方法。我们是不能让连接关闭的,要保持常连接。所以如果用户指定的是保持这个连接,那么返回的连接对象就不是原来的Socket对象了,我们要重写这个对象

package com.socket;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * @说明 被重新定义的连接对象,增加了名字这个属性,重写了关闭的方法
 * @author cuisuqiang
 * @version 1.0
 * @since
 */
public class SocketCui extends Socket{	
	/**
	 * 为对象增加名称属性
	 */
	private String name;	
	public SocketCui() {
	}	
	public SocketCui(String ip,int port) throws UnknownHostException, IOException{
		super(ip, port);
	}	
	/**
	 * 覆盖关闭的方法
	 */
	@Override
	public synchronized void close() throws IOException {
		SocketKeep.socketIsLock.put(this.name, "0");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

 这样,关闭时只会解除其占用,而不会真正关闭该连接。

 

我们来写一个服务端,这个服务端一直接受连接,并检查连接的有效性,当失效时不处理

同时打印接收到的连接信息

package com.test;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @说明 服务端,始终接受连接
 * @author cuisuqiang
 * @version 1.0
 * @since 
 */
public class ServiceTest {
	public static void main(String[] args) {
		try {
			ServerSocket ss1 = new ServerSocket(8001);
			Runnable accumelatora1 = new Accumulatort(ss1);
			Thread threada = new Thread(accumelatora1, "ThreadA");
			threada.start();
			System.out.println("服务启动完毕!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
class Accumulatort implements Runnable {
	ServerSocket ss = null;
	public Accumulatort(ServerSocket s) {
		this.ss = s;
	}
	@SuppressWarnings("unchecked")
	public void run() {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			while (true) {
				Socket s = ss.accept();
				System.out.println(format.format(new Date()) + " " + "---------收到请求!");
				new Thread(new ServiceImpl(s)).start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 服务端处理连接的实现类

package com.test;
import java.net.Socket;
/**
 * @说明 循环发送心跳包保持连接属性
 * @author cuisuqiang
 * @version 1.0
 * @since 
 */
public class ServiceImpl implements Runnable {
	Socket socket = null;
	public ServiceImpl(Socket s) {
		this.socket = s;
	}
	public void run() {
		boolean isKeep = true;
		try {
			while (isKeep) {
				socket.sendUrgentData(0xFF);
				Thread.sleep(1 * 1000);
			}
		} catch (Exception e) {
			isKeep = false;
		}
	}
}

 

先启动服务端,然后我们再写一个测试端,这个测试类会不断去管理器中获取相应的连接,同时打印连接信息

通过打印的连接信息,我们可以知道获取的是不是同一个对象

同时如果你一直获取单例的对象,那么可能出现该连接被检查线程占用的情况

package com.test;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.socket.CommonSocket;
import com.socket.SocketKeep;
/**
 * @说明 循环去请求获得相应的连接然后打印连接地址
 * @author cuisuqiang
 * @version 1.0
 * @since 
 */
public class GetSocketTest {
	public static void main(String[] args) {
		SocketKeep.initSocketKeep();
		while(true){			
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {				
				Socket socket1 = CommonSocket.getSocketByName("socket1");
				if(null != socket1){
					System.out.println(format.format(new Date()) + " " + socket1.toString());
					socket1.close();	
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				Socket socket2 = CommonSocket.getSocketByName("socket2");
				if(null != socket2){
					System.out.println(format.format(new Date()) + " " + socket2.toString());
					socket2.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
				
			}
		}
	}
}

 

当然别忘了加日志的包!

 

我们来看一下服务端的打印信息

服务启动完毕!
2012-04-18 16:59:48 ---------收到请求!
2012-04-18 16:59:48 ---------收到请求!
2012-04-18 16:59:49 ---------收到请求!
2012-04-18 16:59:50 ---------收到请求!
2012-04-18 16:59:51 ---------收到请求!
2012-04-18 16:59:52 ---------收到请求!
2012-04-18 16:59:53 ---------收到请求!
2012-04-18 16:59:54 ---------收到请求!
2012-04-18 16:59:55 ---------收到请求!
2012-04-18 16:59:56 ---------收到请求!
2012-04-18 16:59:57 ---------收到请求!
2012-04-18 16:59:58 ---------收到请求!
2012-04-18 16:59:59 ---------收到请求!

 

我们可以看到,除刚开始外,会一直收到连接,因为我们一直在获取一个非单例的连接对象

我们再看一下客户端打印信息

2012-04-18 16:59:48 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:48 Socket[addr=/127.0.0.1,port=8001,localport=4390]
2012-04-18 16:59:49 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:49 Socket[addr=/127.0.0.1,port=8001,localport=4391]
2012-04-18 16:59:50 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:50 Socket[addr=/127.0.0.1,port=8001,localport=4392]
2012-04-18 16:59:51 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:51 Socket[addr=/127.0.0.1,port=8001,localport=4393]
2012-04-18 16:59:52 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:52 Socket[addr=/127.0.0.1,port=8001,localport=4394]
2012-04-18 16:59:53 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:53 Socket[addr=/127.0.0.1,port=8001,localport=4395]
2012-04-18 16:59:54 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:54 Socket[addr=/127.0.0.1,port=8001,localport=4396]
2012-04-18 16:59:55 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:55 Socket[addr=/127.0.0.1,port=8001,localport=4397]
2012-04-18 16:59:56 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:56 Socket[addr=/127.0.0.1,port=8001,localport=4398]
2012-04-18 16:59:57 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:57 Socket[addr=/127.0.0.1,port=8001,localport=4399]
2012-04-18 16:59:58 Socket[addr=/127.0.0.1,port=8001,localport=4400]
2012-04-18 16:59:59 Socket[addr=/127.0.0.1,port=8001,localport=4389]
2012-04-18 16:59:59 Socket[addr=/127.0.0.1,port=8001,localport=4401]

 

可以看到,socket1是一直被保持的,而socket2每次创建一个

再看一下日志

2012-04-18 16:59:48 [com.socket.SocketKeep]-[WARN] 加载socket.properties文件成功!
2012-04-18 16:59:48 [com.socket.SocketKeep]-[WARN] 加载Socket连接配置信息结束!
2012-04-18 16:59:48 [com.socket.SocketKeep]-[WARN] 开始初始化Socket连接!
2012-04-18 16:59:48 [com.socket.SocketKeep]-[WARN] 初始化Socket连接结束!
2012-04-18 16:59:48 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:48 [com.socket.CheckThread]-[ERROR] 本次检测结束!
2012-04-18 16:59:49 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:50 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:51 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:52 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:53 [com.socket.CheckThread]-[ERROR] 本次检测结束!
2012-04-18 16:59:53 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:54 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:55 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:56 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:57 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:58 [com.socket.CommonSocket]-[WARN] 当前连接正被占用,请稍候尝试!资源名称:socket1
2012-04-18 16:59:58 [com.socket.CheckThread]-[ERROR] 本次检测结束!
2012-04-18 16:59:58 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2
2012-04-18 16:59:59 [com.socket.CommonSocket]-[WARN] 为用户建立请求连接!资源名称:socket2

 

可以看到,socket2会一直被重新创建,而且socket1会发现被占用的情况。

你也可以中断服务端然后再重启服务端试试,看看效果。

 

源码下面可以下载,仅供参考!转载说明出处,谢谢合作!

 

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com

 

15
1
分享到:
评论
4 楼 Javac_bean 2017-11-30  
貌似少了一个java文件哈
package com.socket;
import java.net.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @说明 对外提供的方法
* @author cuisuqiang
* @version 1.0
* @since 得到某个资源使用后必须释放,否则造成霸占使用
*/
public class CommonSocket {
private static Log logger = LogFactory.getLog(CommonSocket.class);
/**
* @说明 通过名字来获得某个连接对象
* @since 如果返回为空,你应该尝试反复调用,因为该对象可能被检测机制占用,或当前不可用
* @since 如果你通过该方法获得了连接对象,那么你应该在使用后显示的关闭该对象的使用,否则该对象会死锁
* @since 如果你尝试获得一个没有被定义的连接,那么会返回NULL
*/
public static Socket getSocketByName(String name) {
SocketCui socket = null;
boolean isHave = false;// 是否有对象的定义
boolean isKeep = false;// 该对象是否为单例
// 检测是否有某个连接的配置信息
for (SocketEntity socketEntity : SocketKeep.socketEntityList) {
if (null != socketEntity) {
if (socketEntity.getName().equals(name)) {
isHave = true;
if (socketEntity.isKeepConn()) {
isKeep = true;
}
break;
}
}
}
// 是否有该名字的配置
if (isHave) {
if (isKeep) {
String isLock = SocketKeep.socketIsLock.get(name);
// 如果当前未锁定
if (null != isLock && !"1".equals(isLock)) {
// 设置占用
SocketKeep.socketIsLock.put(name, "1");
socket = SocketKeep.socketMap.get(name);
try {
// 发送一个心跳包
socket.sendUrgentData(0xFF);
} catch (Exception e) {
logger.error("得到资源后发现资源不可用!资源名称:" + name);
socket = null;
}
} else {
logger.warn("当前连接正被占用,请稍候尝试!资源名称:" + name);
}
} else {
logger.warn("为用户建立请求连接!资源名称:" + name);
// 建立一次性连接
return initSocketByName(name);
}
} else {
logger.error("没有关于该名称的配置信息!资源名称:" + name);
}
return socket;
}
/**
* @说明 根据名称建立一个连接
* @since 需要被创建的连接必须已经加载了配置的信息
*/
private static Socket initSocketByName(String name) {
Socket socket = null;
for (SocketEntity socketEntity : SocketKeep.socketEntityList) {
if (null != socketEntity) {
if (socketEntity.getName().equals(name)) {
try {
socket = new SocketCui(socketEntity.getIp(), socketEntity.getPort());
socket.setSoTimeout(0);
socket.setKeepAlive(true);
// 发送一个心跳包
socket.sendUrgentData(0xFF);
} catch (Exception e) {
logger.error("方法initSocketByName建立连接时错误!", e);
socket = null;
}
}
}
}
return socket;
}
}
3 楼 happycoolyp 2013-11-15  
写的不错。
但是有个疑问,这个是否能保持线程安全呢?

一旦线程运行到判断socketIsLock里的某个socket是可用的的地方 与 设置socket被占用 之间的时候cpu被切换,这个时候是否会出现问题?
2 楼 cuisuqiang 2012-11-28  
a_lee 写道
顶一个
打算将客户端移植到android上不知道要注意什么问题呢
连接数量上有什么问题呢

连接的线程使用连接池管理
1 楼 a_lee 2012-11-28  
顶一个
打算将客户端移植到android上不知道要注意什么问题呢
连接数量上有什么问题呢

相关推荐

    一个Socket连接管理器(心跳机制)

    一个Socket连接管理器(心跳机制)

    socket自动连接和多客户端管理

    socket socket多客户端管理 socket自动连接

    socket线程连接池实例

    socket对象连接池实例,使用GenericObjectPool对象池。

    java socket连接池 实现

    NULL 博文链接:https://516100981.iteye.com/blog/2314314

    Socket连接池的经典实例

    一个java socket连接池的典型实例 SocketClient,客户端测试类 SocketAdapter继承Socket类,重新封装socket类 SocketConnectionPool,连接池管理类 StartupSocketServer,socket服务器端的主线程,负责监听端口,当有...

    Wince建立GPRS连接以便Socket能正常通信

    手机开通GPRS以后,我们的socket 程序还不能直接建立网络连接,需要用连接管理器来获取当前可用连接,并自动选择一个最佳的连接途径,然后启用这个连接,在连接启动成功以后再用socket 进行网络连接方可正常进行。...

    iOS socket连接打印机打印小票

    iOS使用CocoaAsyncSocket连接打印机打印小票,demo封装了socket连接管理类,打印机指令管理类.

    基于Socket的公司员工管理系统

    Swing界面 用Socket进行通信 客户端服务器端分离 用多线程实现一对多连接 内附数据库备份

    Android 通过Socket 和服务器通讯

    (3)开启一个线程,做心跳,防止socket连接终断 , SocketHeartThread (4)构建 SocketThreadManager对以上三个thread进行管理 (5)构建 TCPClient 发送socket消息 在NIO的方式实现TCP,特别是在接收服务器的...

    socket编程(源码)

    调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地...

    Socket编程.pdf

    SOCKET连接过程 Socket常用函数介绍 服务端监听Socket创建步骤 客户端连接Socket创建步骤 IP地址是Internet中主机的标识 Internet中的主机要与别的机器通信必须具有一个IP地址 一个IP地址为32位(IPV4),或者128位...

    java中基于socket的图书管理系统

    本代码是用java编写的基于excel文件操作的图书管理系统,拥有登陆,远程连接,增删改查等功能,并且分服务器端和客户端,他们之间的通信是基于socket的。

    员工管理系统Android版Android客户端socket连接服务器json传输数据jdbc连接MySQL数据库.rar

    员工管理系统Android版Android客户端socket连接服务器json传输数据jdbc连接MySQL数据库.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

    android 2.3以后的socket注意

    android2.3以后,socket的连接需要一个相应的类似网络线程的管理的方法

    开源C# SOCKET服务器

    你可以用它来建立一个服务器端应用程序接口(如游戏服务器,GPS服务器,工业控制系统,数据采集服务器等)容易不假思索有关如何使用套接字,如何维护套接字连接以及如何插座的作品。 它是一个纯C#项目,其目的是...

    socket与serversocket

    socket与serversocket交互信息

    多播 Multicast Socket

    相对于极度消耗网络带宽的广播来说(广播只能在intranet内广播),UDP组播有了很大的优化,只有终端加入到了一个广播组,UDP组播的数据才能被他接受到. UDP组播是采用的无连接,数据报的连接方式,所以是不可靠的....

Global site tag (gtag.js) - Google Analytics