Netty框架的使用

1 TCP开发范例

  发送地址---192.168.31.241
  发送端口号---9223

  发送数据

{
"userid":"mm910@mbk.com",
"devicetype":3,
"accounttype":0,
"username":"",
"password":"e10adc3949ba59abbe56e057f20f883e",
"meiid":1000217,
"deviceid":"864376025909275"
}

  接受数据

{
"message":"登录成功",
"sessionkey":"EF81E1BD132D40DE8F1707A521D8B5A6",
"mainsn":"C001B00010000002",
"code":0
}

2 上代码

1 业务层代码

public class MainActivity extends Activity {

  private Base1106Entity entity1106;// 登录云棒协议

  public static final int RESPONSE_SUCCESS = 0x401;
public static final int RESPONSE_FAIL = 0x402;
public static final int RESPONSE_TIMEOUT = 0x403;
public static final int REQUEST_HEARTBEAT_TIMEOUT = 0x410; //心跳超时
public static final int NOT_LOGIN= 0x411; //用户未登录 public Handler mHandler = new Handler() { @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case RESPONSE_SUCCESS:
IEntity entity = (IEntity) msg.obj;
if (entity != null) {
responseSuccess((IEntity) msg.obj);
} else {
responseFail(-1, "返回数据为空!");
}
break;
case RESPONSE_FAIL:// 请求失败
if (msg != null && msg.obj != null)
responseFail(-10001, (String) msg.obj);
break;
case RESPONSE_TIMEOUT:// 请求超时
if (msg != null && msg.obj != null)
responseFail(-10000, (String) msg.obj);
break;
case NOT_LOGIN:// 用户未登录
if (msg != null && msg.obj != null)
responseFail(-10002, (String) msg.obj);
break;
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button login = (Button)findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
reqEntity1106();
}
}); } public void reqEntity1106() {
entity1106 = new Base1106Entity();
entity1106.setMeiid(1000217);
entity1106.setUserid("mm910@mbk.com");
entity1106.setUsername("");
entity1106.setPassword("e10adc3949ba59abbe56e057f20f883e");
entity1106.setAccounttype( 0 );
entity1106.setDevicetype(3);
entity1106.setDeviceid("864376025909275");
entity1106.setHandler(mHandler);
ClientConnectFactory.getInstance().sendEntity(entity1106);
} public void responseSuccess(IEntity entity) {
Toast.makeText(MainActivity.this, ((Base1106Entity)entity).toString(), Toast.LENGTH_LONG).show();
} public void responseFail(int code, String msg) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
} }
public class MeiApp extends Application{

  public static Context mContext;

  @Override
public void onCreate() {
super.onCreate();
mContext = this; ClientConnectFactory.getInstance().init(mContext);
} }

2 业务通讯层代码

public interface IClientConnect {

  public void isConnect(String netType);

  public void sendAgain();

  public void sendMsgFail(String netType, byte[] msg);

  public void connectFail(String netType);

  // 根据实体发送数据
public void sendEntity(IEntity entity); public void sendByte(byte[] b); // 关闭
public void isClose(); // 清除当前数据
public void isClearMsg(); public void callBack(PackageHeader header, byte[] data, String desc, int type); public void callBack(IEntity entity, String desc);
}
public abstract class BaseClientMgr extends Subject implements IClientConnect {

  protected boolean isRunning; // 当前是否正在连接
protected boolean isSending; // 是否正在发送 线程是否被占用
private int mPort; // 连接服务器的端口号
private int mCommunication; // 通讯类型
private int heartTimeOutCount = 0; // 记录心跳超时次数
protected int function = 1200; // 关闭连接功能号 public static final int RESPONSE_SUCCESS = 0x401;
public static final int RESPONSE_FAIL = 0x402;
public static final int RESPONSE_TIMEOUT = 0x403;
public static final int REQUEST_HEARTBEAT_TIMEOUT = 0x410; // 心跳超时
public static final int NOT_LOGIN = 0x411; // 用户未登录 private String mConnectKey = "BasicServicesMgr";
private String mHost; // 连接服务器的IP地址
protected ArrayList<IEntity> mEntityMsg = null; // 待发送消息集合 protected Context mContext; // Context对象
protected CommunicationThreadManager mManager; // 该通讯层管理器
protected ParseByteThread mParseByteThread = null; // 数据解析线程
protected ExecutorService executor; // 线程连接池 protected BaseClientMgr(String host, int port, String key) {
init(host, port, key);
} // 初始化
private void init(String host, int port, String key) {
this.mContext = MeiApp.mContext;
isRunning = false;
isSending = false;
mHost = host;
mPort = port;
mConnectKey = key;
mEntityMsg = new ArrayList<IEntity>();
executor = Executors.newFixedThreadPool(10);
mParseByteThread = new ParseByteThread(this);
executor.execute(mParseByteThread);
} protected Handler basicHandler = new Handler() { @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case ClientConstants.REQUEST:
// 发送请求 连接占用
if (mEntityMsg != null && mEntityMsg.size() > 0) {
isSending = true;
// 清除handler的消息
basicHandler.removeMessages(ClientConstants.REQUEST);
basicHandler.removeMessages(ClientConstants.REQUEST_CREATE_CONNECT);
basicHandler.removeMessages(ClientConstants.REQUEST_SEND_MESSAGE);
// 请求类型 当为网络请求时判断网络状态 建立连接
// 检查连接是否可用
if (isRunning) {
// 直接发送消息
basicHandler.removeMessages(ClientConstants.REQUEST_SEND_MESSAGE);
basicHandler.sendEmptyMessage(ClientConstants.REQUEST_SEND_MESSAGE);
} else {
// 建立连接
basicHandler.removeMessages(ClientConstants.REQUEST_CREATE_CONNECT);
Message msgCreate = Message.obtain();
msgCreate.what = ClientConstants.REQUEST_CREATE_CONNECT;
msgCreate.arg1 = 0;
basicHandler.sendMessage(msgCreate);
} }
break;
case ClientConstants.REQUEST_CREATE_CONNECT:
// 建立连接
Log.i("mbk", "建立连接!");
isConnect("netty"); break;
case ClientConstants.REQUEST_SEND_MESSAGE:
// 发送消息
Log.i("mbk", "发送消息!");
if (isRunning) {
if (mEntityMsg.size() > 0) {
Log.i("mbk", "发送数据!");
sendData(mEntityMsg.get(0));
basicHandler.removeMessages(ClientConstants.REQUEST_TIMEOUT);
// 设置请求超时
basicHandler.sendEmptyMessageDelayed(ClientConstants.REQUEST_TIMEOUT, 3000);
} else {
Log.i("mbk", "数据发送完成!");
isSending = false;
}
} else {
// 重新建立连接
basicHandler.removeMessages(ClientConstants.REQUEST_CREATE_CONNECT);
basicHandler.sendEmptyMessage(ClientConstants.REQUEST_CREATE_CONNECT);
}
break;
case ClientConstants.REQUEST_SEND_HEARTBEAT:
Log.i("mbk", "发送心跳!");
mManager.sendHeart(function);
heartTimeOutCount++;
Log.i("lzy02", "heartTimeOutCount---------------" + heartTimeOutCount);
if (heartTimeOutCount >= 3) {// 大于等于3则认为与云棒无连接
callBack(null, null, "心跳超时!", REQUEST_HEARTBEAT_TIMEOUT);
}
// // 发送心跳
basicHandler.removeMessages(ClientConstants.REQUEST_SEND_HEARTBEAT);
basicHandler.sendEmptyMessageDelayed(ClientConstants.REQUEST_SEND_HEARTBEAT, 3000); break;
case ClientConstants.REQUEST_TIMEOUT:// 请求超时
Log.i("mbk", "请求超时!");
isRunning = false;
callBack(null, null, "请求超时!", RESPONSE_TIMEOUT);
break; }
}
}; public void sendHeartbeat(int function) {
this.function = function;
} public void sendData(IEntity entity) {
sendByte(ClientSocketUtils.sendDatas(mEntityMsg.get(0)));
} // 建立连接
@Override
public void isConnect(String netType) {
UdpEntity udpEntity = null;
int type = CommunicationThreadManager.MBK_COMMUNICATION_NETTY;
if (netType.equals("netty")) {
// 建立一个netty连接
type = CommunicationThreadManager.MBK_COMMUNICATION_NETTY; mManager = new CommunicationThreadManager(mContext, null, mConnectKey, "192.168.31.241", mPort, type, mCommunicationCallBack); Log.i("mbk", "发送地址---" + "192.168.31.241");
Log.i("mbk", "发送端口号---" + mPort); /*
* if (udpEntity != null) { Log.i("lzy02",
* "udpEntity---209----------udpEntity=="+udpEntity.getYunbangIp());
* mManager = new CommunicationThreadManager(mContext, null, mConnectKey,
* "192.168.31.241", mPort, type, mCommunicationCallBack);
* //Toast.makeText(mContext, "已通过Netty发送 ", Toast.LENGTH_SHORT).show();
* Log.i("mbk","netty发送云棒IP号---" + udpEntity.getYunbangIp()); } else {
* Log.i("lzy02", "udpEntity---211----------udpEntity == null");
* callBack(null, null, "无法连接netty!", RESPONSE_FAIL); }
*/
// 使用netty是时候 清理p2p
P2pClearUp();
} else { }
Log.i("mbk", "初始化 连接服务器!" + netType);
} @Override
public void sendByte(byte[] b) {
try {
if (mManager != null) {
mManager.sendDataToServer(new SendData(b));
} else {
isClose();
}
} catch (InterruptedException e) {
isClose();
}
} // 服务端回调
private CommunicationCallBack mCommunicationCallBack = new CommunicationCallBack() { @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Log.i("mbk", "--------------------------请求异常--------------------------" + mCommunication);
isRunning = false;
callBack(null, null, "请求异常!", RESPONSE_FAIL); } @Override
public void connected(ChannelHandlerContext ctx) {
Log.i("mbk", "--------------------------连接成功--------------------------" + mCommunication);
// mChx = ctx;
isRunning = true;
sendAgain();
} @Override
public void connectFailure(Exception e) {
Log.i("mbk", "--------------------------连接服务器失败--------------------------" + mCommunication);
isRunning = false;
callBack(null, null, "连接服务器失败!", RESPONSE_FAIL);
} @Override
public void channelRead(ChannelHandlerContext ctx, byte[] msg) {
Log.i("mbk", "--------------------------服务端返回--------------------------" + mCommunication);
if (mParseByteThread != null) {
mParseByteThread.sendParseByte(msg);
}
} @Override
public void communicationOutTime() {
Log.i("mbk", "--------------------------连接超时--------------------------" + mCommunication);
isRunning = false;
callBack(null, null, "连接超时!", RESPONSE_TIMEOUT);
} @Override
public void questTimeOut() {
Log.i("mbk", "--------------------------请求超时--------------------------" + mCommunication);
isRunning = false;
callBack(null, null, "请求超时!", RESPONSE_TIMEOUT);
}
}; @Override
public void sendAgain() {
// 连接成功 发起请求
Log.i("mbk", "连接成功,数据重新发送!"); // basicHandler.sendEmptyMessage(ClientConstants.REQUEST_SEND_MESSAGE);
basicHandler.sendEmptyMessageDelayed(ClientConstants.REQUEST_SEND_MESSAGE, 500);
} // 接收需要发送的实体
@Override
public void sendEntity(IEntity entity) {
if (mEntityMsg != null && entity != null) {
mEntityMsg.add(entity);
if (!isSending) {
// 启动一个发送
Log.i("mbk", "发起请求!REQUEST_NET");
basicHandler.sendEmptyMessage(ClientConstants.REQUEST);
}
}
// if (mEntityMsg != null && mEntityMsg.size() == 2) {
// mEntityMsg.remove(1);
// } } @Override
public void callBack(PackageHeader header, byte[] data, String desc, int type) {
basicHandler.removeMessages(ClientConstants.REQUEST_SEND_HEARTBEAT); switch (type) {
case RESPONSE_SUCCESS:
heartTimeOutCount = 0;
basicHandler.sendEmptyMessageDelayed(ClientConstants.REQUEST_SEND_HEARTBEAT, 20000);
switch (header.getFunction()) {
case 9998:
Log.i("mbk", "服务端关闭!");
isClose();
break;
case 9999:
Log.i("mbk", "成功返回一个心跳!");
break;
case 999:
Log.i("mbk", "未知错误!");
callBack(null, null, "未知错误", RESPONSE_FAIL);
break;
default:
responseSuccess(header, data, desc, type);
break;
}
break;
case REQUEST_HEARTBEAT_TIMEOUT:// 心跳超时3次认为与云棒无连接
/*
* Intent m2Intent = new Intent(MeiConfigs.NETWORK_PROMPT);
* m2Intent.putExtra("islogin", "3003");
* MeiApp.mContext.sendBroadcast(m2Intent);
*/
break;
case RESPONSE_FAIL:
responseFail(header, data, desc, type);
break;
case RESPONSE_TIMEOUT:
responseFail(header, data, desc, type);
break;
}
} // 请求成功
public void responseSuccess(PackageHeader header, byte[] data, String desc, int type) { try {
if (mEntityMsg.size() > 0 && mEntityMsg.get(0).getHandler() != null) {
IEntity entity = mEntityMsg.get(0);
if (data != null && data.length > 0) {
entity.onDecode(new String(data, "utf-8"));
// Log.i("mbk","云棒返回---" + "---" + new String(data, "utf-8"));
// 请求成功 Log.i("lzy02", "1--------------" + entity.getCode());
Log.i("mbk", "返回一条数据!");
Message msg = Message.obtain();
msg.obj = entity;
msg.arg1 = header.getFunction();
msg.what = type;
entity.getHandler().sendMessage(msg);
}
}
} catch (Exception e) {
e.printStackTrace();
isClose();
}
if (mEntityMsg != null && mEntityMsg.size() > 0) {
mEntityMsg.remove(0);
}
basicHandler.removeMessages(ClientConstants.REQUEST_TIMEOUT);
isSending = false;
if (mEntityMsg.size() > 0) {
basicHandler.sendEmptyMessage(ClientConstants.REQUEST);
}
} // 请求失败
public void responseFail(PackageHeader header, byte[] data, String desc, int type) {
Log.i("mbk", "请求失败! " + desc);
Message msg = Message.obtain();
msg.obj = desc;
msg.arg1 = 0;
msg.what = type;
if (mEntityMsg.size() > 0 && mEntityMsg.get(0).getHandler() != null) {
mEntityMsg.get(0).getHandler().sendMessage(msg);
}
isClose();
} // 请求本地缓存返回
@Override
public void callBack(IEntity entity, String desc) {
Log.i("mbk", "回一返个缓存数据! ");
if ("cache".equals(desc)) {
if (entity != null && entity.getHandler() != null) {
Message msg = Message.obtain();
msg.obj = entity;
msg.what = RESPONSE_SUCCESS;
entity.getHandler().sendMessage(msg);
}
}
} public void P2pClearUp() {
if (mManager != null) {
mManager.p2pCleanup();
}
} @Override
public void isClose() {
Log.i("mbk", "关闭连接!" + isRunning);
if (mManager != null) {
if (isRunning) {
try {
mManager.sendDataToServer(new SendData(ClientSocketUtils.sendExit(function)));
} catch (InterruptedException e) {
}
} else {
mManager.closeTheadManager();
mManager = null;
}
}
if (mParseByteThread != null)
mParseByteThread.closeThread();
if (mEntityMsg != null) {
mEntityMsg.clear();
}
P2pClearUp();
basicHandler.removeMessages(ClientConstants.REQUEST_SEND_HEARTBEAT);
basicHandler.removeMessages(ClientConstants.REQUEST_TIMEOUT);
isRunning = false;
isSending = false;
} @Override
public void sendMsgFail(String netType, byte[] msg) {
} @Override
public void connectFail(String netType) {
} @Override
public void isClearMsg() {
if (mEntityMsg != null) {
mEntityMsg.clear();
}
} }
public class BasicServicesMgr extends BaseClientMgr {

  public static BasicServicesMgr instance = null;

  public static BasicServicesMgr getInstance() {
if (instance == null) {
instance = new BasicServicesMgr();
}
return instance;
} private BasicServicesMgr() {
super( "192.168.43.1", 9223, ClientConnectorManager.BASIC_SERVICES_MGR_KEY);
} //接收需要发送的实体
@Override
public void sendEntity(IEntity entity) {
if (entity != null) { // 请求列表每次最多保存两个请求
if (mEntityMsg != null && mEntityMsg.size() == 2) {
mEntityMsg.remove(1);
}
mEntityMsg.add(entity);
if (!isSending) {
// 启动一个发送
isSending = true;
basicHandler.sendEmptyMessage(ClientConstants.REQUEST);
} }
}
}
public interface Observer {

  //更新接口
public void update(IEntity state);
}
class ParseByteThread implements Runnable {

  private byte[] bufHeader = null;
private byte[] readData = null;
private PackageHeader header = null;
private int headerLenth = PackageHeader.headerLenth;
private int readDataLenth = 0;
private int sLength = 0;// 添加到数组的长度
private Handler fileParseHandler = null;
private IClientConnect connect; public static final int RESPONSE_SUCCESS = 0x401;
public static final int RESPONSE_FAIL = 0x402;
public static final int RESPONSE_TIMEOUT = 0x403;
/** 心跳超时 */
public static final int REQUEST_HEARTBEAT_TIMEOUT = 0x410;
/** 用户未登录 */
public static final int NOT_LOGIN= 0x411; public Handler getFileParseHandler() {
return this.fileParseHandler;
} public void sendParseByte(byte[] msg) {
if (fileParseHandler != null) {
Message msgData = Message.obtain();
msgData.obj = msg;
fileParseHandler.sendMessage(msgData);
}
} public ParseByteThread(IClientConnect connect) {
readDataLenth = 0;
sLength = 0;
headerLenth = PackageHeader.headerLenth;
bufHeader = new byte[PackageHeader.headerLenth];
readData = null;
header = new PackageHeader();
this.connect = connect;
} public void setFileParseHandler(Handler fileParseHandler) {
this.fileParseHandler = fileParseHandler;
} public void closeThread(){
readDataLenth = 0;
sLength = 0;
headerLenth = PackageHeader.headerLenth;
bufHeader = new byte[PackageHeader.headerLenth];
readData = null;
header = new PackageHeader();
}
@Override
public void run() { Looper.prepare();
fileParseHandler = new Handler() {
public void handleMessage(Message data) {
synchronized (data) {
byte[] msg = (byte[]) data.obj;
if (msg == null) {
return;
}
int msgLength = msg.length;
int useLength = 0;// 已经使用的长度
while (msgLength - useLength > 0) {
// 读取包头
if (readDataLenth == 0) {
if (msgLength - useLength >= headerLenth - sLength) {
// 读取了一个完整的包头
System.arraycopy(msg, useLength, bufHeader, sLength, headerLenth - sLength);
useLength += (headerLenth - sLength);
sLength = 0;
header.setPackageHeader(bufHeader);
if (header.getFunction() > 10000 || header.getFunction() < 999) {
// 包头不符合,跳出循环 放弃整包
connect.callBack(null, null, "包头不符合", RESPONSE_FAIL);
break;
}
if (header.getFunction() != 9999 && header.getFunction() != 9998) {
readDataLenth = (int) header.getInclusionLenth();
readData = null;
readData = new byte[readDataLenth];
} else if (header.getFunction() == 9999) {
// 发送心跳包
connect.callBack(header, readData, "", RESPONSE_SUCCESS);
} else if (header.getFunction() == 9998) {
msgLength = 0;
useLength = 0;
connect.callBack(header, readData, "", RESPONSE_SUCCESS);
}
} else { System.arraycopy(msg, useLength, bufHeader, sLength, msgLength - useLength);
sLength += (msgLength - useLength);
break;
}
}
// 读取包体
else {
if (msgLength - useLength >= readDataLenth - sLength) {
// 读取了一个完整的包体
System.arraycopy(msg, useLength, readData, sLength, readDataLenth - sLength);
useLength += (readDataLenth - sLength);
sLength = 0;
readDataLenth = 0;
bufHeader = null;
bufHeader = new byte[PackageHeader.headerLenth];
// 解析成功 返回数据
try {
connect.callBack(header, readData, "", RESPONSE_SUCCESS);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.arraycopy(msg, useLength, readData, sLength, msgLength - useLength);
sLength += (msgLength - useLength);
break;
}
}
}
}
}
};
Looper.loop();
}
}
public abstract class Subject {

  //用来保存注册的观察者对象
private List<Observer> list = new ArrayList<Observer>(); private Handler subHandler = new Handler(MeiApp.mContext.getMainLooper()) {
public void handleMessage(Message msg) {
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
list.get(i).update((IEntity) msg.obj);
}
}
}
}; //注册观察者对象
public void attach(Observer observer) {
if (list != null) {
list.add(observer);
}
} //删除观察者对象
public void detach(Observer observer) {
if (list != null && list.size() > 0 && observer != null) {
list.remove(observer); }
} //删除观察者对象
public void clear() { if (list != null && list.size() > 0) {
list.clear();
} } //通知所有注册的观察者对象
public void nodifyObservers(final IEntity newState) { new Thread(new Runnable() { @Override
public void run() {
Message msg = Message.obtain();
msg.obj = newState;
subHandler.sendMessage(msg); }
}).start(); }
}

代码见https://github.com/huanyi0723/NettyTest

  

Android Netty框架的使用的更多相关文章

  1. Android 开源框架Universal-Image-Loader学习

    Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析(二)--- 图片 ...

  2. Android 数据库框架OrmLite的使用(一)

    在这里记录下最基本的用法,官网上可了解相关的介绍. 1.下载OrmLite jar 在下载android的:ormlite-android-4.48.jar和ormlite-core-4.48.jar ...

  3. Android 开源框架Universal-Image-Loader完全解析(三)---源代码解读

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/39057201),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  4. Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  5. 淘宝(阿里百川)手机客户端开发日记第一篇 android 主框架搭建(一)

    android 主框架搭建(一) 1.开发环境:Android Studio 相继点击下一步,直接项目建立完毕(如下图) 图片看的效果如果很小,请放大您的浏览器显示百分比  转载请注明http://w ...

  6. Android Xutils 框架(转)

    Android Xutils 框架 (转) 目录(?)[-] xUtils简介 目前xUtils主要有四大模块 使用xUtils快速开发框架需要有以下权限 混淆时注意事项 DbUtils使用方法 Vi ...

  7. Android测试框架初步

    一.实验目的 1.掌握android测试项目的建立 2.掌握android测试框架的基本内容 3.编写运行android测试 二.实验内容与步骤 建立android项目MyProject,运行截图如下 ...

  8. Android自动化测试框架对比

    1.Monkeyrunner:优点:操作最为简单,可以录制测试脚本,可视化操作:缺点:主要生成坐标的自动化操作,移植性不强,功能最为局限:2.Rubotium:主要针对某一个APK进行自动化测试,AP ...

  9. Android MVVM框架RoboBinding初探

    RoboBinding是一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架.MVVM模式是MVC模式的重要更新,使得项目结构更加的优美,易于维护以及方便 ...

随机推荐

  1. hdu 1061 Rightmost Digit

    解决本题使用数学中的快速幂取余: 该方法总结挺好的:具体参考http://www.cnblogs.com/PegasusWang/archive/2013/03/13/2958150.html #in ...

  2. Sudoku

    Sudoku Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15952 Accepted: 7791 Special Judge ...

  3. view class source code with JAD plugin in Eclipse

    The default class viewer doesn't decompile the class file so you cannot open and check the source co ...

  4. httpclient4.3.6/httpcore-4.4自己封装的工具类

    引入jar包 httpclient4.3.6/httpcore-4.4 package com.develop.util; import java.io.IOException; import jav ...

  5. range函数

    th> a=torch.range(,) [.0001s] th> a [torch.DoubleTensor of size ] [.0002s] th> a=torch.rang ...

  6. Codeforces Round #370 (Div. 2) C

    Description Memory is now interested in the de-evolution of objects, specifically triangles. He star ...

  7. 2016年6月30日 星期四 --出埃及记 Exodus 14:27

    2016年6月30日 星期四 --出埃及记 Exodus 14:27 Moses stretched out his hand over the sea, and at daybreak the se ...

  8. Jenkins构建Git manager服务器的源码

    1,下载scm manager 源码库管理,下载后解压即可: 2,运行bin目录下的scm-server.bat文件,启动服务: 3,建议将scm-server放在git客户端的安装目录下,方便管理 ...

  9. haha

    [问题描述] 栈是一种强大的数据结构,它的一种特殊功能是对数组进行排序.例如,借助一个栈,依次将数组1,3,2按顺序入栈或出栈,可对其从大到小排序:1入栈:3入栈:3出栈:2入栈:2出:1出栈.在上面 ...

  10. sql 邮件发送测试情况

    sql 邮件发送测试情况 select * from msdb.dbo.sysmail_allitems select * from msdb.dbo.sysmail_event_log