HttpClient(联网)
抽样:
void GameRequest::initRequset(const char* url, cocos2d::CCObject* pTarget, cocos2d::SEL_CallFuncND pSelector)
{
cocos2d::extension::CCHttpRequest* request = new cocos2d::extension::CCHttpRequest();
request->setUrl(url);
//设置为GET请求:kHttpGet
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpGet);
//设置处理响应回调函数
if(pTarget != NULL && pSelector != NULL){
request->setResponseCallback(pTarget, pSelector);
}
cocos2d::extension::CCHttpClient::getInstance()->setTimeoutForConnect(15);
cocos2d::extension::CCHttpClient::getInstance()->setTimeoutForRead(15);
cocos2d::extension::CCHttpClient::getInstance()->send(request);
int countme = request->retainCount();
if(countme <= 0)
{
CCLOG("=request retaincount==================%d",request->retainCount());
}
request->release();
}
void CoverScene::checkUserNameRequestCallBack(cocos2d::CCNode *sender, void *data)
{
cocos2d::extension::CCHttpResponse *response = (cocos2d::extension::CCHttpResponse*)data;
if (!response)
{
return;
}
//你能够使用: response->request->reqType获取请求类型
if (0 != strlen(response->getHttpRequest()->getTag()))
{
CCLog("%s completed", response->getHttpRequest()->getTag());
}
//获取状态码
int statusCode = response->getResponseCode();
char statusString[64] = {};
sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
CCLog("response code: %d", statusCode);
if (!response->isSucceed())
{
//訪问失败获取错误信息
CCLog("response failed");
CCLog("error buffer: %s", response->getErrorBuffer());
return;
}
try {
vector::data
指针到 vector
类 的第一个元素成功或为空 vector的位置。
std::vector<char> *buffer = response->getResponseData();
std::string str = std::string(buffer->data(), buffer->size());
Json *dataJson = Json_create(str.data());
std::cout<<Json_getSize(dataJson)<<std::endl;
MessageBoxLayer::getMessageBoxPoint()->callMessageBoxRemove();
if (Json_getSize(dataJson) == 1)
{
//账号password错误
CCLOG("账号password错误.........");
changeToLogin();
}
else
{
Json *infoDataJson = Json_getItem(dataJson, "data");
m_accessToken = Json_getItem(infoDataJson,"token")->valuestring;
GameUser::GetGameUser()->uninqueId = atoll(Json_getItemAt(Json_getItemAt(dataJson, 1),0)->valuestring);
GameUser::GetGameUser()->platform_user_id = Json_getString(infoDataJson, "platform_user_id", "");//Json_String(infoDataJson, "platform_user_id");
CoverScene::m_iType = 0;
getServerListRequest();
}
}
catch (const std::exception& rhs)
{
CCLOG("数据异常");
}
#ifndef __CCHTTPREQUEST_H__
#define __CCHTTPREQUEST_H__
#include "cocos2d.h"
#include "ExtensionMacros.h"
#include "HttpRequest.h"
#include "HttpResponse.h"
NS_CC_EXT_BEGIN
/**
* @addtogroup Network
* @{
*/
/** @brief Singleton that handles(操控) asynchronous(asyn 异步 chromous
同步) http requests
* Once the request completed, a callback will issued(公布) in main thread when it provided during make request
*/
class CCHttpClient : public CCObject
{
public:
/** Return the shared instance **/
static CCHttpClient *getInstance();// CCHttpClient
是一个单例类
/** Relase the shared instance **/
static voiddestroyInstance();
{
CCAssert(s_pHttpClient, "");
CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(CCHttpClient::dispatchResponseCallbacks), s_pHttpClient);
s_pHttpClient->release();
}
/**
* Add a get request to task queue
* @param request a CCHttpRequest object, which includes url, response callback etc.
please make sure request->_requestData is clear before calling "send" here.
* @return NULL
*/
voidsend(CCHttpRequest* request);//这个用的最多 将CCHttpRequest 增加请求列表
/**
* Change the connect timeout
* @param timeout
* @return NULL
*/
inline voidsetTimeoutForConnect(int value) {_timeoutForConnect = value;};//设置连接超时
时间值
/**
* Get connect timeout
* @return int
*
*/
inline int getTimeoutForConnect() {return _timeoutForConnect;}//获得连接时间
/**
* Change the download timeout
* @param value
* @return NULL
*/
inline voidsetTimeoutForRead(int value) {_timeoutForRead = value;};
/**
* Get download timeout
* @return int
*/
inline intgetTimeoutForRead() {return _timeoutForRead;};
private:
CCHttpClient();//单例类
: _timeoutForConnect(30)
, _timeoutForRead(60)
{
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(
schedule_selector(CCHttpClient::dispatchResponseCallbacks), this, 0, false);
CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
}
virtual ~CCHttpClient();
//当类是在栈上 类在离开作用域时会调用析构函数释放空间,此时无法调用私有的析构函数
//假设在堆上分配空间,仅仅有在delete时才会调用析构函数。
////////////////////////析构函数私有
当我们规定类仅仅能在堆上分配内存时,就能够将析构函数声明为私有的。
class alloc
{
public:
alloc():
private:
~alloc();
};
假设在栈上分配空间。类在离开作用域时会调用析构函数释放空间,此时无法调用私有的析构函数。
假设在堆上分配空间。仅仅有在delete时才会调用析构函数。
能够加入一个destroy()函数来释放,从而解决不能在析构函数中加入delete的问题。
class alloc
{
public:
alloc():
destroy(){ delete this;}
private:
~alloc();
};
/////////////////////////////////////////////////////
bool init(void);
/**
* Init pthread mutex, semaphore, and create new thread for http requests
* @return bool
*/
boollazyInitThreadSemphore(); // 私有函数 无需深究
用到了很多额外函数 cpp里写的
{
if (s_requestQueue != NULL) {
return true;
} else {
s_requestQueue = new CCArray();
s_requestQueue->init();
s_responseQueue = new CCArray();
s_responseQueue->init();
pthread_mutex_init(&s_requestQueueMutex, NULL);
pthread_mutex_init(&s_responseQueueMutex, NULL);
pthread_mutex_init(&s_SleepMutex, NULL);
pthread_cond_init(&s_SleepCondition, NULL);
pthread_create(&s_networkThread, NULL, networkThread, NULL);
pthread_detach(s_networkThread);
need_quit = false;
}
return true;
}
//Poll function called from main thread to dispatch callbacks when http requests finished
// Poll and notify main thread if responses exists in queue
voiddispatchResponseCallbacks(float delta); //
分发网络回应 私有函数 无需深究
private:
int _timeoutForConnect;
int _timeoutForRead;
// std::string reqId;
};
// end of Network group
/// @}
NS_CC_EXT_END
#endif //__CCHTTPREQUEST_H__
作用域 生存期 static extern..........
#include "HttpClient.h"
// #include "platform/CCThread.h"
#include <queue>
#include <pthread.h>
#include <errno.h>
#include "curl/curl.h"
NS_CC_EXT_BEGIN
static pthread_t s_networkThread;
static pthread_mutex_t s_requestQueueMutex;
static pthread_mutex_t s_responseQueueMutex;
static pthread_mutex_ts_SleepMutex;
static pthread_cond_ts_SleepCondition;
static unsigned long s_asyncRequestCount = 0;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
typedef int int32_t;
#endif
static bool need_quit = false;
static CCArray* s_requestQueue = NULL;
static CCArray* s_responseQueue = NULL;
static CCHttpClient *s_pHttpClient = NULL; // pointer to singleton
static char s_errorBuffer[CURL_ERROR_SIZE];
typedef size_t (*write_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
// Callback function used by libcurl for collect response data
static size_t writeData(void *ptr, size_t size, size_t nmemb, void *stream)
{
std::vector<char> *recvBuffer = (std::vector<char>*)stream;
size_t sizes = size * nmemb;
// add data to the end of recvBuffer
// write data maybe called more than once in a single request
recvBuffer->insert(recvBuffer->end(), (char*)ptr, (char*)ptr+sizes);
return sizes;
}
// Callback function used by libcurl for collect header data
static size_t writeHeaderData(void *ptr, size_t size, size_t nmemb, void *stream)
{
std::vector<char> *recvBuffer = (std::vector<char>*)stream;
size_t sizes = size * nmemb;
// add data to the end of recvBuffer
// write data maybe called more than once in a single request
recvBuffer->insert(recvBuffer->end(), (char*)ptr, (char*)ptr+sizes);
return sizes;
}
static int processGetTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *errorCode, write_callback headerCallback, void *headerStream);
static int processPostTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *errorCode, write_callback headerCallback, void *headerStream);
static int processPutTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *errorCode, write_callback headerCallback, void *headerStream);
static int processDeleteTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *errorCode, write_callback headerCallback, void *headerStream);
// int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode);
// Worker thread
static void* networkThread(void *data)
{
CCHttpRequest *request = NULL;
while (true)
{
if (need_quit)
{
break;
}
// step 1: send http request if the requestQueue isn't empty
request = NULL;
pthread_mutex_lock(&s_requestQueueMutex); //Get request task from queue
if (0 != s_requestQueue->count())
{
request = dynamic_cast<CCHttpRequest*>(s_requestQueue->objectAtIndex(0));
s_requestQueue->removeObjectAtIndex(0);
// request's refcount = 1 here
}
pthread_mutex_unlock(&s_requestQueueMutex);
if (NULL == request)
{
// Wait for http request tasks from main thread
pthread_cond_wait(&s_SleepCondition, &s_SleepMutex);
continue;
}
// step 2: libcurl sync access
// Create a HttpResponse object, the default setting is http access failed
CCHttpResponse *response = new CCHttpResponse(request);
// request's refcount = 2 here, it's retained by HttpRespose constructor
request->release();
// ok, refcount = 1 now, only HttpResponse hold it.
int32_t responseCode = -1;
int retValue = 0;
// Process the request -> get response packet
switch (request->getRequestType())
{
case CCHttpRequest::kHttpGet: // HTTP GET
retValue = processGetTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case CCHttpRequest::kHttpPost: // HTTP POST
retValue = processPostTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case CCHttpRequest::kHttpPut:
retValue = processPutTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case CCHttpRequest::kHttpDelete:
retValue = processDeleteTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
default:
CCAssert(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
break;
}
// write data to HttpResponse
response->setResponseCode(responseCode);
if (retValue != 0)
{
response->setSucceed(false);
response->setErrorBuffer(s_errorBuffer);
}
else
{
response->setSucceed(true);
}
// add response packet into queue
pthread_mutex_lock(&s_responseQueueMutex);
s_responseQueue->addObject(response);
pthread_mutex_unlock(&s_responseQueueMutex);
// resume dispatcher selector
CCDirector::sharedDirector()->getScheduler()->resumeTarget(CCHttpClient::getInstance());
}
// cleanup: if worker thread received quit signal, clean up un-completed request queue
pthread_mutex_lock(&s_requestQueueMutex);
s_requestQueue->removeAllObjects();
pthread_mutex_unlock(&s_requestQueueMutex);
s_asyncRequestCount -= s_requestQueue->count();
if (s_requestQueue != NULL) {
pthread_mutex_destroy(&s_requestQueueMutex);
pthread_mutex_destroy(&s_responseQueueMutex);
pthread_mutex_destroy(&s_SleepMutex);
pthread_cond_destroy(&s_SleepCondition);
s_requestQueue->release();
s_requestQueue = NULL;
s_responseQueue->release();
s_responseQueue = NULL;
}
pthread_exit(NULL);
return 0;
}
//Configure curl's timeout property
static bool configureCURL(CURL *handle)
{
if (!handle) {
return false;
}
int32_t code;
code = curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, s_errorBuffer);
if (code != CURLE_OK) {
return false;
}
code = curl_easy_setopt(handle, CURLOPT_TIMEOUT, CCHttpClient::getInstance()->getTimeoutForRead());
if (code != CURLE_OK) {
return false;
}
code = curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, CCHttpClient::getInstance()->getTimeoutForConnect());
if (code != CURLE_OK) {
return false;
}
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
return true;
}
class CURLRaii
{
/// Instance of CURL
CURL *m_curl;
/// Keeps custom header data
curl_slist *m_headers;
public:
CURLRaii()
: m_curl(curl_easy_init())
, m_headers(NULL)
{
}
~CURLRaii()
{
if (m_curl)
curl_easy_cleanup(m_curl);
/* free the linked list for header data */
if (m_headers)
curl_slist_free_all(m_headers);
}
template <class T>
bool setOption(CURLoption option, T data)
{
return CURLE_OK == curl_easy_setopt(m_curl, option, data);
}
/**
* @brief Inits CURL instance for common usage
* @param request Null not allowed
* @param callback Response write callback
* @param stream Response write stream
*/
bool init(CCHttpRequest *request, write_callback callback, void *stream, write_callback headerCallback, void *headerStream)
{
if (!m_curl)
return false;
if (!configureCURL(m_curl))
return false;
/* get custom header data (if set) */
std::vector<std::string> headers=request->getHeaders();
if(!headers.empty())
{
/* append custom headers one by one */
for (std::vector<std::string>::iterator it = headers.begin(); it != headers.end(); ++it)
m_headers = curl_slist_append(m_headers,it->c_str());
/* set custom headers for curl */
if (!setOption(CURLOPT_HTTPHEADER, m_headers))
return false;
}
return setOption(CURLOPT_URL, request->getUrl())
&& setOption(CURLOPT_WRITEFUNCTION, callback)
&& setOption(CURLOPT_WRITEDATA, stream)
&& setOption(CURLOPT_HEADERFUNCTION, headerCallback)
&& setOption(CURLOPT_HEADERDATA, headerStream);
}
/// @param responseCode Null not allowed
bool perform(int *responseCode)
{
if (CURLE_OK != curl_easy_perform(m_curl))
return false;
CURLcode code = curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, responseCode);
if (code != CURLE_OK || *responseCode != 200)
return false;
// Get some mor data.
return true;
}
};
//Process Get Request
static int processGetTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *responseCode, write_callback headerCallback, void *headerStream)
{
CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream)
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.perform(responseCode);
return ok ?
0 : 1;
}
//Process POST Request
static int processPostTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *responseCode, write_callback headerCallback, void *headerStream)
{
CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream)
&& curl.setOption(CURLOPT_POST, 1)
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
&& curl.perform(responseCode);
return ok ? 0 : 1;
}
//Process PUT Request
static int processPutTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *responseCode, write_callback headerCallback, void *headerStream)
{
CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream)
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "PUT")
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
&& curl.perform(responseCode);
return ok ?
0 : 1;
}
//Process DELETE Request
static int processDeleteTask(CCHttpRequest *request, write_callback callback, void *stream, int32_t *responseCode, write_callback headerCallback, void *headerStream)
{
CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream)
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "DELETE")
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.perform(responseCode);
return ok ? 0 : 1;
}
// HttpClient implementation
CCHttpClient* CCHttpClient::getInstance()
{
if (s_pHttpClient == NULL) {
s_pHttpClient = new CCHttpClient();
}
return s_pHttpClient;
}
void CCHttpClient::destroyInstance()
{
CCAssert(s_pHttpClient, "");
CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(CCHttpClient::dispatchResponseCallbacks), s_pHttpClient);
s_pHttpClient->release();
}
CCHttpClient::CCHttpClient()
: _timeoutForConnect(30)
, _timeoutForRead(60)
{
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(
schedule_selector(CCHttpClient::dispatchResponseCallbacks), this, 0, false);
CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
}
CCHttpClient::~CCHttpClient()
{
need_quit = true;
if (s_requestQueue != NULL) {
pthread_cond_signal(&s_SleepCondition);
}
s_pHttpClient = NULL;
}
//Lazy create semaphore & mutex & thread
bool CCHttpClient::lazyInitThreadSemphore()
{
if (s_requestQueue != NULL) {
return true;
} else {
s_requestQueue = new CCArray();
s_requestQueue->init();
s_responseQueue = new CCArray();
s_responseQueue->init();
pthread_mutex_init(&s_requestQueueMutex, NULL);
pthread_mutex_init(&s_responseQueueMutex, NULL);
pthread_mutex_init(&s_SleepMutex, NULL);
pthread_cond_init(&s_SleepCondition, NULL);
pthread_create(&s_networkThread, NULL, networkThread, NULL);
pthread_detach(s_networkThread);
need_quit = false;
}
return true;
}
//Add a get task to queue
void CCHttpClient::send(CCHttpRequest* request)
{
if (false == lazyInitThreadSemphore())
{
return;
}
if (!request)
{
return;
}
++s_asyncRequestCount;
request->retain();
pthread_mutex_lock(&s_requestQueueMutex);
s_requestQueue->addObject(request);
pthread_mutex_unlock(&s_requestQueueMutex);
// Notify thread start to work
pthread_cond_signal(&s_SleepCondition);
}
// Poll and notify main thread if responses exists in queue
void CCHttpClient::dispatchResponseCallbacks(float delta)
{
// CCLog("CCHttpClient::dispatchResponseCallbacks is running");
CCHttpResponse* response = NULL;
pthread_mutex_lock(&s_responseQueueMutex);
if (s_responseQueue->count())
{
response = dynamic_cast<CCHttpResponse*>(s_responseQueue->objectAtIndex(0));
s_responseQueue->removeObjectAtIndex(0);
}
pthread_mutex_unlock(&s_responseQueueMutex);
if (response)
{
--s_asyncRequestCount;
CCHttpRequest *request = response->getHttpRequest();
CCObject *pTarget = request->getTarget();
SEL_HttpResponse pSelector = request->getSelector();
if (pTarget && pSelector)
{
(pTarget->*pSelector)(this, response);
}
response->release();
}
if (0 == s_asyncRequestCount)
{
CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
}
}
NS_CC_EXT_END
版权声明:本文博主原创文章,博客,未经同意不得转载。
HttpClient(联网)的更多相关文章
- 论述Android通过HttpURLConnection与HttpClient联网代理网关设置
Android联网主要使用HttpURLConneciton和HttpClient进行联网,在手机联网的时候,我们优先选择wifi网络,其次在选择移动网络,这里所述移动网络主要指cmwap. 大家都知 ...
- 转-Android联网 — HttpURLConnection和HttpClient选择哪个好?
http://www.ituring.com.cn/article/199619?utm_source=tuicool 在Android开发中,访问网络我们是选择HttpURLConnection还是 ...
- android两种基本联网方式与一种第三方开源项目的使用
安卓请求网络的三种方式 在请求网络的时候一般常用的提交方式是post或者get请求,post请求安全,传输大小无限制,但是代码量多些,get请求是浏览器有大小限制,用户提交的信息在浏览器的地址栏显示出 ...
- Logstash5.0.X离线安装插件报错,仍然提示无法联网
本人最初将此解决方案发布在 ELK中文社区 http://elasticsearch.cn/question/1046 由于生产环境无法连接互联网,所有再一台联网机器上将所有插件做了 pack 拖到生 ...
- android之HttpClient
Apache包是对android联网访问封装的很好的一个包,也是android访问网络最常用的类. 下面分别讲一下怎么用HttpClient实现get,post请求. 1.Get 请求 HttpGet ...
- android HTTPclient
Apache包是对android联网访问封装的很好的一个包,也是android访问网络最常用的类. 下面分别讲一下怎么用HttpClient实现get,post请求. 1.Get 请求 1 2 3 4 ...
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 【Cocos2d-x】 HttpClient 网络通信(Http)的简单应用
Cocos2dx 为我们封装了在cocos2dx中http的网络框架,其文件在cocos2dx引擎包的extensions\network文件下的 HttpClient.HttpRequest .Ht ...
- HTTPClient模块的HttpGet和HttpPost
HttpClient常用HttpGet和HttpPost这两个类,分别对应Get方式和Post方式. 无论是使用HttpGet,还是使用HttpPost,都必须通过如下3步来访问HTTP资源. 1.创 ...
随机推荐
- bootstrap之WaitForIdle&&Clear
(上篇文章写完才发现.说好的按顺序可是回头一看全然不是按顺序的)明明WaitForIdle才是第一个.哎,老了,后脑勺不行了. WaitForIdle package io.appium.androi ...
- DM8168硬件平台
DM8168硬件平台 作者:Marvin_wu TMS320DM8168是一款多核SoC,它集成了包含ARM Cortex A8.DSP C674X+.M3 VIDEO.M3 VPSS等处理器.DS ...
- Swift - 点击输入框外部屏幕关闭虚拟键盘
我们如果把文本框的Return Key设置成Done,然后在storyboard中将文本框的Did End On Exit事件在代码里进行关联.同时关联代码里调用文本框的resignFirstResp ...
- 『openframeworks』shader制作三角形马赛克效果
不久前做了六边形马赛克的效果,很有意思,乘热打铁,弄了个三角形马赛克. 首先肯定是等边三角形,这样才能真正的无缝拼接.观察发现,三角形可以拼接成之前做个的六边形. 如下图: 我们可以发现6个三角形正好 ...
- 积累的VC编程小技巧之滚动条
1.设置滚动条的滚动大小 创建一个基于CScrollview的SDI Project(在第6步中选CScrollview) 若你已创建了,这步可以省略. 然后: 改为如 void CTestView: ...
- Mac必备软件推荐
阅读原文http://littlewhite.us/archives/245 随着IOS的流行.Mac电脑也越来越多的进入人们的视野,和iPhone系列一样,苹果的Mac产品线也是软硬件完美结合.有着 ...
- SQL ---指令实例语句
1 1 create database+数据库名字 创建数据库 2 2 create table+表的名字 创建表 3 表中的操作: 4 3 insert into 表名 (列名1,列名2··)val ...
- 文档数据库RavenDB-介绍与初体验
文档数据库RavenDB-介绍与初体验 阅读目录 1.RavenDB概述与特性 2.RavenDB安装 3.C#开发初体验 4.RavenDB资源 不知不觉,“.NET平台开源项目速览“系列文章已经1 ...
- 与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态
原文:与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态 [索引页][源码下载] 与众不同 windows phone (23) - Devic ...
- 14.3.2.1 Transaction Isolation Levels 事务隔离级别
14.3.2 InnoDB Transaction Model InnoDB 事务模型 14.3.2.1 Transaction Isolation Levels 事务隔离级别 14.3.2.2 au ...