Http与Socket连接池-java(android)
2016-03-11 18:17
369 查看
》Http连接池
package xiaogang.enif.net;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import xiaogang.enif.utils.IOUtils;
import android.content.Context;
import android.net.Proxy;
import android.text.TextUtils;
/**
** 连接池支持http、https;
** 支持wap网络;
*/
public class HttpManager {
private static final int DEFAULT_MAX_CONNECTIONS = 30;
private static final int DEFAULT_SOCKET_TIMEOUT = 20 * 1000;
private static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;
private static DefaultHttpClient sHttpClient;
static {
final HttpParams httpParams = new BasicHttpParams();
ConnManagerParams.setTimeout(httpParams, 1000);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(10));
ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, "UTF-8");
HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
HttpClientParams.setRedirecting(httpParams, false);
HttpProtocolParams.setUserAgent(httpParams, "Android client");
HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
HttpConnectionParams.setTcpNoDelay(httpParams, true);
HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
schemeRegistry.register(new Scheme("https", sf, 443));
} catch (Exception ex) {
// do nothing, just keep not crash
}
ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
sHttpClient = new DefaultHttpClient(manager, httpParams);
}
private HttpManager() {
}
public static HttpResponse execute(HttpHead head) throws IOException {
return sHttpClient.execute(head);
}
public static HttpResponse execute(HttpHost host, HttpGet get) throws IOException {
return sHttpClient.execute(host, get);
}
public static HttpResponse execute(Context context, HttpGet get) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setWapProxy();
return sHttpClient.execute(get);
}
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
return sHttpClient.execute(get);
}
private static void setSinaWapProxy() {
final HttpHost para = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (para != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
String host = Proxy.getDefaultHost();
int port = Proxy.getDefaultPort();
HttpHost httpHost = new HttpHost(host, port);
HttpParams httpParams = new BasicHttpParams();
httpParams.setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);
}
public static HttpResponse execute(Context context, HttpUriRequest post) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setSinaWapProxy();
}
return sHttpClient.execute(post);
}
public static HttpResponse execute(Context context, HttpPost post) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setWapProxy();
return sHttpClient.execute(post);
}
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
return sHttpClient.execute(post);
}
private static boolean isWapNetwork() {
final String proxyHost = android.net.Proxy.getDefaultHost();
return !TextUtils.isEmpty(proxyHost);
}
private static void setWapProxy() {
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host == null) {
final String host1 = Proxy.getDefaultHost();
int port = Proxy.getDefaultPort();
HttpHost httpHost = new HttpHost(host1, port);
sHttpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);
}
}
private static class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {
tm
}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}
》 Socket连接池
1. socet信息类
2. 链接池工具
package xiaogang.enif.net;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import xiaogang.enif.utils.IOUtils;
import android.content.Context;
import android.net.Proxy;
import android.text.TextUtils;
/**
** 连接池支持http、https;
** 支持wap网络;
*/
public class HttpManager {
private static final int DEFAULT_MAX_CONNECTIONS = 30;
private static final int DEFAULT_SOCKET_TIMEOUT = 20 * 1000;
private static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;
private static DefaultHttpClient sHttpClient;
static {
final HttpParams httpParams = new BasicHttpParams();
ConnManagerParams.setTimeout(httpParams, 1000);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(10));
ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, "UTF-8");
HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
HttpClientParams.setRedirecting(httpParams, false);
HttpProtocolParams.setUserAgent(httpParams, "Android client");
HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);
HttpConnectionParams.setTcpNoDelay(httpParams, true);
HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
schemeRegistry.register(new Scheme("https", sf, 443));
} catch (Exception ex) {
// do nothing, just keep not crash
}
ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
sHttpClient = new DefaultHttpClient(manager, httpParams);
}
private HttpManager() {
}
public static HttpResponse execute(HttpHead head) throws IOException {
return sHttpClient.execute(head);
}
public static HttpResponse execute(HttpHost host, HttpGet get) throws IOException {
return sHttpClient.execute(host, get);
}
public static HttpResponse execute(Context context, HttpGet get) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setWapProxy();
return sHttpClient.execute(get);
}
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
return sHttpClient.execute(get);
}
private static void setSinaWapProxy() {
final HttpHost para = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (para != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
String host = Proxy.getDefaultHost();
int port = Proxy.getDefaultPort();
HttpHost httpHost = new HttpHost(host, port);
HttpParams httpParams = new BasicHttpParams();
httpParams.setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);
}
public static HttpResponse execute(Context context, HttpUriRequest post) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setSinaWapProxy();
}
return sHttpClient.execute(post);
}
public static HttpResponse execute(Context context, HttpPost post) throws IOException {
if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {
setWapProxy();
return sHttpClient.execute(post);
}
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host != null) {
sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);
}
return sHttpClient.execute(post);
}
private static boolean isWapNetwork() {
final String proxyHost = android.net.Proxy.getDefaultHost();
return !TextUtils.isEmpty(proxyHost);
}
private static void setWapProxy() {
final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(
ConnRouteParams.DEFAULT_PROXY);
if (host == null) {
final String host1 = Proxy.getDefaultHost();
int port = Proxy.getDefaultPort();
HttpHost httpHost = new HttpHost(host1, port);
sHttpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);
}
}
private static class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {
tm
}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}
》 Socket连接池
1. socet信息类
package cn.richinfo.cloudp.dm.common.util; import java.net.Socket; /** * @Crop 深圳市xxx科技有限公司 * @author liuxingmi * @QQ 63972012 * @DateTime 2014-8-25 下午3:21:19 * @Desc 名字服务器连接信息 */ public class SocketInfo { /** * socket */ private Socket socket; /** * 是否空闲 (是:true 否:false) */ private boolean isFree; /** * socket id */ private Integer socketId; /** * 是否为可关闭链接 (是:true 否:false) */ private boolean isClosed; public Socket getSocket() { return socket; } public void setSocket(Socket socket) { this.socket = socket; } public boolean isFree() { return isFree; } public void setFree(boolean isFree) { this.isFree = isFree; } public Integer getSocketId() { return socketId; } public void setSocketId(Integer socketId) { this.socketId = socketId; } public boolean isClosed() { return isClosed; } public void setClosed(boolean isClosed) { this.isClosed = isClosed; } }
2. 链接池工具
package cn.richinfo.cloudp.dm.common.util; import java.io.IOException; import java.net.Socket; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import cn.richinfo.cloudp.common.config.CloudpConfigUtil; import cn.richinfo.cloudp.common.constant.ConfigConst; import cn.richinfo.cloudp.common.log.DMLogger; /** * @Crop 深圳市xxxx有限公司 * @author liuxingmi * @QQ 63972012 * @DateTime 2014-8-25 下午3:18:18 * @Desc 分布式名字服务器socket链接池 */ public class SocketPool { private static DMLogger logger = DMLogger.getInstance();//日志类 /** * socketMap */ public static ConcurrentHashMap<Integer, SocketInfo> socketMap = new ConcurrentHashMap<Integer, SocketInfo>(); private static SocketPool instance = new SocketPool(); private SocketPool(){} public static SocketPool getInstance(){ if(instance == null){ synchronized (SocketPool.class) { if(instance == null){ instance = new SocketPool(); } } } return instance; } static { instance.initSocket(true); } /** * @DateTime 2014-8-25 下午3:18:52 * @User liuxingmi * @Desc 初始化链接池 * @param isAllReInit 是否全部重新初始化 * @return void */ public void initSocket(boolean isAllReInit){ int defaultCount = Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT); logger.info("nameserver:initSocket", DMLogger.RESULT_OK, "开始初始化分布式名字服务器连接数:" + defaultCount); for (int i = 0; i < defaultCount; i++) { if(isAllReInit){ socketMap.put(i, setSocketInfo( i, true, false)); } else { if(socketMap.get(i) == null || socketMap.get(i).isClosed()){ socketMap.put(i, setSocketInfo( i, true, false)); } } } logger.info("nameserver:initSocket", DMLogger.RESULT_OK, "完成初始化分布式名字服务器连接数"); new CheckSocketThread().start(); } /** * @DateTime 2014-8-26 上午10:06:13 * @User liuxingmi * @Desc 设置socketInfo值 * @param socket * @param key * @param isFree * @param isClosed * @return SocketInfo */ private static SocketInfo setSocketInfo(Integer key, boolean isFree, boolean isClosed){ SocketInfo socketInfo = new SocketInfo(); Socket socket = createSocket(); socketInfo.setFree(isFree); socketInfo.setSocket(socket); socketInfo.setSocketId(key); socketInfo.setClosed(isClosed); return socketInfo; } /** * @DateTime 2014-8-25 下午3:19:06 * @User liuxingmi * @Desc 获取名字服务器链接 * @return * SocketInfo */ public SocketInfo getSocketInfo(){ SocketInfo socketInfo = null; if(socketMap.size() < Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT)){ initSocket(false); } if(socketMap.size() > 0){ for (Map.Entry<Integer, SocketInfo> entry : socketMap.entrySet()) { socketInfo = entry.getValue(); if(socketInfo.isFree() && ! socketInfo.getSocket().isClosed()){ socketInfo.setFree(false); return socketInfo; } } } else { logger.info("nameserver:socketInfo", DMLogger.RESULT_FAIL, "名字服务器socket连接池数量为零。"); return null; } logger.info("nameserver:socketInfo", DMLogger.RESULT_OK, "所有名字服务器socket链接都忙,创建临时链接。"); socketInfo = setSocketInfo(-1, true, true); logger.info("nameserver:socketInfo", DMLogger.RESULT_OK, "成功创建服务器socket临时链接。"); return socketInfo; } /** * 释放socket * @param socketId */ public static void distorySocket(Integer socketId){ logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "释放名字服务器socket链接。"); SocketInfo socketInfo = socketMap.get(socketId); socketInfo.setFree(true); } /** * @DateTime 2014-8-25 下午3:19:42 * @User liuxingmi * @Desc 释放socket * @param socketInfo * void */ public static void distorySocket(SocketInfo socketInfo){ if(socketInfo == null) return; if( ! socketInfo.isClosed()){ logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "链接池socket,释放资源。"); distorySocket(socketInfo.getSocketId()); return; } logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "可关闭临时链接,关闭socket"); try { if(socketInfo.getSocket() != null){ socketInfo.getSocket().close(); } } catch (IOException e) { logger.error("nameserver:distorySocket", DMLogger.RESULT_FAIL, "关闭名字服务器socket链接失败", e); } socketInfo = null; } /** * @DateTime 2014-8-25 下午3:19:51 * @User liuxingmi * @Desc 创建socket * @return * Socket */ public static Socket createSocket(){ String nameServerip1 = CloudpConfigUtil.DM_CONFIG.getNameSerIP1(); int namServerport1 = CloudpConfigUtil.DM_CONFIG.getNameSerPort1(); String nameServerip2 = CloudpConfigUtil.DM_CONFIG.getNameSerIP2(); int namServerport2 = CloudpConfigUtil.DM_CONFIG.getNameSerPort2(); Socket socket = null; try {// 尝试通过ip1第一次建立连接 socket = new Socket(nameServerip1, namServerport1); logger.info("nameserver:login", DMLogger.RESULT_OK, "nameServerip1:" + nameServerip1 + ", namServerport1:" + namServerport1); } catch (IOException e) { logger.error("nameserver:login", DMLogger.RESULT_FAIL, "first link fail nameServerip1:" + nameServerip1 + ", namServerport1:" + namServerport1, e); try { // 如果第一次通过ip1建立连接失败,则进行第二次连接 socket = new Socket(nameServerip2, namServerport2); logger.info("nameserver:login", DMLogger.RESULT_OK, "nameServerip2:" + nameServerip2 + ", namServerport2:" + namServerport2); } catch (IOException e1) { logger.error("nameserver:login", DMLogger.RESULT_FAIL, "second link fail nameServerip2:" + nameServerip2 + ", namServerport2:" + namServerport2, e); return null; } } return socket; } class CheckSocketThread extends Thread{ @Override public void run() { while (true) { logger.debug("nameserver:checkSocket", DMLogger.RESULT_OK, "开始检测分布式链接状态。"); if(socketMap.size() < Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT)){ logger.info("nameserver:checkSocket", DMLogger.RESULT_OK, "分布式名字服务器socket链接小于默认链接数,增加socket链接。"); initSocket(false); } for (Map.Entry<Integer, SocketInfo> entry : socketMap.entrySet() ) { SocketInfo socketInfo = entry.getValue(); if(socketInfo.getSocket() == null || socketInfo.isClosed()){ logger.error("nameserver:checkSocket", DMLogger.RESULT_FAIL, "第"+ entry.getKey()+"个socket链接已关闭,重新连接分布式。",null); socketInfo.setSocket(createSocket()); } else { if(socketInfo.isFree()){ boolean flag = NameServerUtils.getInstance().checkHeartbeat(socketInfo); if( ! flag ){ logger.error("nameserver:checkSocket", DMLogger.RESULT_FAIL, "第"+ entry.getKey()+"个socket链接失败,重新连接分布式。",null); socketInfo.setSocket(createSocket()); continue; } } logger.debug("nameserver:checkSocket", DMLogger.RESULT_OK, "第"+ entry.getKey()+"个socket链接正常。"); } } try { sleep(Long.valueOf(ConfigConst.SOCKET_CHECK_TIME)); } catch (Exception e) { } } } } }
相关文章推荐
- Struts 中获取session、request及response对象的方法(http://lieva.iteye.com/blog/1328513)
- UPnP基本原理介绍
- ASIHTTPRequest的使用与NSXMLParser的解析。
- AsyncTask异步任务使用详细实例(一)+HttpClient+进度更新的设置
- Mac 有线网络或WiFi网络共享成WiFiwifi的方法
- HTTP返回值
- HttpClient上传下载Demo
- 小米手机TCP连接一些奇怪现象
- 关于文件、网络传输以及内存存储的大小端问题
- HttpClient模拟登陆
- 替换Servlet容器的HttpSession实现集群中Session共享(With Redis)
- TCP的连接建立和释放(三次握手和四次握手)
- Http协议
- IOS 使用AF网络请求统一RSA加密+URL不识别中文的解决办法
- TCP传输控制协议 读书笔记
- 关于TCP和UDP的异同点
- iOS----网络开发之第三方库AFNetworking
- [转]Linux服务器上11种网络连接状态 和 TCP三次握手/四次挥手详解
- 计算机网络之运输层
- Netscaler 10.5 VPX与XenApp XenDesktop 集成配置系列之一基本网络配置