muduo_inspect库源码分析(41)

muduo的inspect库以及TCP的Keep-Alive时间分析 一:源码分析     今天剖析muduo inspect库。muduo_inspect库通过HTTP的方式为服务器提供监控接口。比如提供以下功能: 接收了多少个TCP连接当前有多少个活动连接一共响应了多少次请求每次请求的平均响应时间为多少ms...     inspect库主要有Inspector类组成,它包含了一个HttpServer对象,并同过ProcessInspector类返 阅读详情

muduo_inspect库通过HTTP方式为服务器提供监控接口
接受了多少个TCP连接
当前有多少个活动连接
一共响应了多少次请求
每次请求的平均响应时间多少毫秒
。。。

Inspector     // 包含了一个HttpServer对象
ProcessInspector // 通过ProcessInfo返回进程信息

ProcessInfo // 获取进程相关信息





ProcessInspectort头文件

ProcessInspector.h

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.

// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is an internal header file, you should not include this.

#ifndef MUDUO_NET_INSPECT_PROCESSINSPECTOR_H
#define MUDUO_NET_INSPECT_PROCESSINSPECTOR_H

#include <muduo/net/inspect/Inspector.h>
#include <boost/noncopyable.hpp>

namespace muduo
{
namespace net
{

class ProcessInspector : boost::noncopyable
{
 public:
  void registerCommands(Inspector* ins);    // 注册命令接口

 private:
  static string pid(HttpRequest::Method, const Inspector::ArgList&);
  static string procStatus(HttpRequest::Method, const Inspector::ArgList&);
  static string openedFiles(HttpRequest::Method, const Inspector::ArgList&);
  static string threads(HttpRequest::Method, const Inspector::ArgList&);

};

}
}

#endif  // MUDUO_NET_INSPECT_PROCESSINSPECTOR_H




ProcessInspectort源文件

ProcessInspector.cc


// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.

// Author: Shuo Chen (chenshuo at chenshuo dot com)
//

#include <muduo/net/inspect/ProcessInspector.h>
#include <muduo/base/ProcessInfo.h>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

/*命令注册*/
void ProcessInspector::registerCommands(Inspector* ins)
{
  /*muduo             :   proc
    command           :   pid
    commandCallback   :   pid
    commnadHelp       :   print id
  */
  ins->add("proc", "pid", ProcessInspector::pid, "print pid");
  ins->add("proc", "status", ProcessInspector::procStatus, "print /proc/self/status");
  ins->add("proc", "opened_files", ProcessInspector::openedFiles, "count /proc/self/fd");
  ins->add("proc", "threads", ProcessInspector::threads, "list /proc/self/task");
}

string ProcessInspector::pid(HttpRequest::Method, const Inspector::ArgList&)
{
  char buf[32];
  snprintf(buf, sizeof buf, "%d", ProcessInfo::pid());
  return buf;
}

string ProcessInspector::procStatus(HttpRequest::Method, const Inspector::ArgList&)
{
  return ProcessInfo::procStatus();
}

string ProcessInspector::openedFiles(HttpRequest::Method, const Inspector::ArgList&)
{
  char buf[32];
  snprintf(buf, sizeof buf, "%d", ProcessInfo::openedFiles());
  return buf;
}

string ProcessInspector::threads(HttpRequest::Method, const Inspector::ArgList&)
{
  std::vector<pid_t> threads = ProcessInfo::threads();
  string result;
  for (size_t i = 0; i < threads.size(); ++i)
  {
    char buf[32];
    snprintf(buf, sizeof buf, "%d\n", threads[i]);
    result += buf;
  }
  return result;
}





Inspector头文件

Inspector.h

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.

// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is a public header file, it must only include public header files.

#ifndef MUDUO_NET_INSPECT_INSPECTOR_H
#define MUDUO_NET_INSPECT_INSPECTOR_H

#include <muduo/base/Mutex.h>
#include <muduo/net/http/HttpRequest.h>
#include <muduo/net/http/HttpServer.h>

#include <map>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>

namespace muduo
{
namespace net
{

class ProcessInspector;

// A internal inspector of the running process, usually a singleton.
class Inspector : boost::noncopyable
{
 public:
  typedef std::vector<string> ArgList;
  typedef boost::function<string (HttpRequest::Method, const ArgList& args)> Callback;
  Inspector(EventLoop* loop,
            const InetAddress& httpAddr,
            const string& name);
  ~Inspector();

  // 如add("proc", "pid", ProcessInspector::pid, "print pid");
  // http://192.168.159.188:12345/proc/pid这个http请求就会相应的调用ProcessInspector::pid来处理
  void add(const string& module,
           const string& command,
           const Callback& cb,
           const string& help);

 private:
  typedef std::map<string, Callback> CommandList;
  typedef std::map<string, string> HelpList;

  void start();
  void onRequest(const HttpRequest& req, HttpResponse* resp);

  HttpServer server_;
  boost::scoped_ptr<ProcessInspector> processInspector_;
  MutexLock mutex_;
  std::map<string, CommandList> commands_;
  std::map<string, HelpList> helps_;
  /*
commands_ --- > <muduo commandlist>
helps_    ----> <muduo helplist>

commandlist---> <command callback>
HelpList  ----> <command helplist>

commands_[][]=xx
helps_[][]=xxx 

  */
};

}
}

#endif  // MUDUO_NET_INSPECT_INSPECTOR_H




Inspector源文件

Inspector.cc

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.

// Author: Shuo Chen (chenshuo at chenshuo dot com)
//

#include <muduo/net/inspect/Inspector.h>

#include <muduo/base/Thread.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/http/HttpRequest.h>
#include <muduo/net/http/HttpResponse.h>
#include <muduo/net/inspect/ProcessInspector.h>

//#include <iostream>
//#include <iterator>
//#include <sstream>
#include <boost/bind.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

using namespace muduo;
using namespace muduo::net;

namespace
{
Inspector* g_globalInspector = 0;

// Looks buggy
std::vector<string> split(const string& str)
{
  std::vector<string> result;
  size_t start = 0;
  size_t pos = str.find('/');
  while (pos != string::npos)
  {
    if (pos > start)
    {
      result.push_back(str.substr(start, pos-start));
    }
    start = pos+1;
    pos = str.find('/', start);
  }

  if (start < str.length())      // 说明最后一个字符不是'/'
  {
    result.push_back(str.substr(start));
  }

  return result;
}

}

Inspector::Inspector(EventLoop* loop,
                     const InetAddress& httpAddr,
                     const string& name)
    : server_(loop, httpAddr, "Inspector:"+name),
      processInspector_(new ProcessInspector)
{
  //断言在主线程当中
  assert(CurrentThread::isMainThread());
  assert(g_globalInspector == 0);
  g_globalInspector = this;
  /*设置请求的回调函数,这里的请求是完成了协议的解析之后*/
  server_.setHttpCallback(boost::bind(&Inspector::onRequest, this, _1, _2));
  /*注册命令*/
  processInspector_->registerCommands(this);
  // 这样子做法是为了防止竞态问题
  // 如果直接调用start,(当前线程不是loop所属的IO线程,是主线程)那么有可能,当前构造函数还没返回,
  // HttpServer所在的IO线程可能已经收到了http客户端的请求了(因为这时候HttpServer已启动),那么就会回调
  // Inspector::onRequest,而这时候构造函数还没返回,也就是说对象还没完全构造好。那么就会出现问题了
  loop->runAfter(0, boost::bind(&Inspector::start, this)); // little race condition
}

Inspector::~Inspector()
{
  assert(CurrentThread::isMainThread());
  g_globalInspector = NULL;
}

void Inspector::add(const string& module,
                    const string& command,
                    const Callback& cb,
                    const string& help)
{
  /*这里要不要加锁??
因为在构造函数时 程序是注册完 processInspector_->registerCommands(this); 才执行
loop->runAfter(0, boost::bind(&Inspector::start, this)); // little race condition。

如果程序进行扩充时,就要了。
class TcpInspector : boost::noncopyable
{
 public:
  void registerCommands(Inspector* ins);  // 注册命令接口

 private:
  static string pid(HttpRequest::Method, const Inspector::ArgList&);
  static string procStatus(HttpRequest::Method, const Inspector::ArgList&);
  static string openedFiles(HttpRequest::Method, const Inspector::ArgList&);
  static string threads(HttpRequest::Method, const Inspector::ArgList&);

};

MyInspector :public ProcessInspector
{
   TcpInspector
} ;
那么
MyInspector{

  HttpServer server_;
  boost::scoped_ptr<ProcessInspector> processInspector;
  boost::scoped_ptr<ProcessInspector> TcpInspector;
  MutexLock mutex_;
  std::map<string, CommandList> commands_;
  std::map<string, HelpList> helps_;
}
那么MyInspector 在初始化时,会初始化ProcessInspector 和TcpInspector,
如果ProcessInspector初始化完毕后,启动了OnreRequest(),而TcpInspector还没注册完,
也就是说TcpInspector还在add()函数中,那么不加锁的话,就会出现问题了。
  */
  MutexLockGuard lock(mutex_);
  commands_[module][command] = cb;
  helps_[module][command] = help;
}

void Inspector::start()
{
  server_.start();
}

void Inspector::onRequest(const HttpRequest& req, HttpResponse* resp)
{
  if (req.path() == "/")
  {
    string result;
    MutexLockGuard lock(mutex_);
    // 遍历helps 
    for (std::map<string, HelpList>::const_iterator helpListI = helps_.begin();
         helpListI != helps_.end();
         ++helpListI)
    {
      const HelpList& list = helpListI->second;
      for (HelpList::const_iterator it = list.begin();
           it != list.end();
           ++it)
      {
        result += "/";
        result += helpListI->first;      // module
        result += "/";
        result += it->first;         // command
        result += "\t";
        result += it->second;            // help
        result += "\n";
      }
    }
    resp->setStatusCode(HttpResponse::k200Ok);
    resp->setStatusMessage("OK");
    resp->setContentType("text/plain");
    resp->setBody(result);
  }
  else
  {
    // 以"/"进行分割,将得到的字符串保存在result中
    std::vector<string> result = split(req.path());
    // boost::split(result, req.path(), boost::is_any_of("/"));
    //std::copy(result.begin(), result.end(), std::ostream_iterator<string>(std::cout, ", "));
    //std::cout << "\n";
    bool ok = false;
    if (result.size() == 0)
    {
      // 这种情况是错误的,因此ok仍为false
    }
    else if (result.size() == 1)
    {
      // 只有module,没有command也是错的,因此ok仍为false
      string module = result[0];
    }
    else
    {
      string module = result[0];
      // 查找module所对应的命令列表
      std::map<string, CommandList>::const_iterator commListI = commands_.find(module);
      if (commListI != commands_.end())
      {
        string command = result[1];
        const CommandList& commList = commListI->second;
        // 查找command对应的命令
        CommandList::const_iterator it = commList.find(command);
        if (it != commList.end())
        {
          ArgList args(result.begin()+2, result.end());     // 传递给回调函数的参数表
          if (it->second)
          {
            resp->setStatusCode(HttpResponse::k200Ok);
            resp->setStatusMessage("OK");
            resp->setContentType("text/plain");
            const Callback& cb = it->second;
            resp->setBody(cb(req.method(), args));       // 调用cb将返回的字符串传给setBody
            ok = true;
          }
        }
      }

    }

    if (!ok)
    {
      resp->setStatusCode(HttpResponse::k404NotFound);
      resp->setStatusMessage("Not Found");
    }
    //resp->setCloseConnection(true);
  }
}




测试程序

#include <muduo/net/inspect/Inspector.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/EventLoopThread.h>

using namespace muduo;
using namespace muduo::net;

int main()
{
  EventLoop loop;
  EventLoopThread t;    // 监控线程 ,这里“线程该没有真正创建,t.startLoop()函数才是真正创建”
  /*Inspector 的loop 和main thread 的loop是不一样的,也就是说,现在已经有两个loop了*/
  Inspector ins(t.startLoop(), InetAddress(12345), "test");
  loop.loop();
}


在浏览器中输入127.0.0.1:12345/proc/status

Name:   inspector_test
State:  S (sleeping)
Tgid:   2030
Pid:    2030
PPid:   1907
TracerPid:  0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 20 24 46 116 118 124 1000 
VmPeak:    12348 kB
VmSize:    12348 kB
VmLck:         0 kB
VmHWM:      1580 kB
VmRSS:      1580 kB
VmData:     8408 kB
VmStk:       136 kB
VmExe:       860 kB
VmLib:      2868 kB
VmPTE:        32 kB
VmSwap:        0 kB
Threads:    2
SigQ:   0/9772
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   3
Cpus_allowed_list:  0-1
Mems_allowed:   1
Mems_allowed_list:  0
voluntary_ctxt_switches:    22
nonvoluntary_ctxt_switches: 14



详细muduo的使用(二)——安装与使用 Muduo是什么? muduo是陈硕大神个人开发的C++的TCP网络编程库。muduo基于Reactor模式实现。Reactor模式也是目前大多数Linux端高性能网络编程框架和网络应用所选择的主要架构,例如内存数据库Redis和Java的Netty库等。 陈硕的《Linux多线程服务器端编程》一书对muduo整个架构进行了非常详尽的介绍和分析,可以说是学习muduo源码和设计理念最好的资料了... 阅读详情

相关推荐

python: inspect模块各函数的用法

inspect模块也被称为 检查现场对象。这里的重点在于“现场”二字,也就是当前运行的状态。inspect模块提供了一些函数来了解现场对象,包括 模块、类、实例、函数和方法。inspect函数主要用于以下四个方面。

weixin_43915090的博客 939

muduo网络库学习之muduo_inspect 库涉及到的类

muduo inspect 库通过HTTP方式为服务器提供监控接口, 现在只实现进程相关信息的监控,通过成员ProcessInspector 实现。 ProcessInspector // 通过ProcessInfo返回进程信息      ProcessInfo // 获取进程相关信息 我们可以参照 ProcessInspector 实现一个如TcpStateInspector,作为

Meditation 3918

muduo库手册

感觉不错,分享一下,它的使用手册,希望它对你有帮助

(P41)muduo_inspect库源码分析:muduo_inspect库通过HTTP方式为服务器提供监控接口

文章目录1.muduo_inspect库通过HTTP方式为服务器提供监控接口 1.muduo_inspect库通过HTTP方式为服务器提供监控接口 接受了多少个TCP连接 当前有多少个活动连接 一共响应了多少次请求 每次请求的平均响应时间多少毫秒 。。。 Inspector // 包含了一个HttpServer对象 ProcessInspector // 通过ProcessInfo返回进程信息 ProcessInfo // 获取进程相关信息,muduo_base库中已做了解

喜欢打篮球的普通人 528

inspect

检查 小型CLI可以查询图像的元数据以尝试确定其来源。 当前仅适用于生成到GitHub的比较链接。 安装 brew tap garethjevans/tap brew install inspect 可以将其与以下内容一起用于docker容器: docker run -it garethjevans/inspect 用法 检查图像 inspect image <image> 例如 inspect image jenkinsciinfra/terraform 将产生类似于以下内容的输出: +------------------------------------------+----------------------------------------------------------------+ | LABEL

微软inspect.exe(类似 Spy++、UI Spy)

请使用最新版解压缩软件解压,或者使用7-zip解压 微软的东西 在Windows 8.1 SDK中有带 类似 Spy++ / UI Spy,可以查看窗口及其内各种元素,可pinvoke 详细描述在此链接 http://technet.microsoft.com/zh-cn/magazine/dd318521(en-us,VS.85).aspx 用Dependency Walker看了下DLL依赖,都是系统的,应该可以直接用的吧,谁用过后回复反馈一下

python模块—inspect_inspect

inspect的主要作用。

m0_60634964的博客 1477

微软inspect x86

微软控件识别工具X86,支持大部分控件,自动化测试的必备工具

发布一个基于 Reactor 模式的 C++ 网络库

Muduo 是我在业余时间编写的基于 Reactor 模式的 C++ 网络库,适用于 Linux 平台,支持多线程。本文主要介绍 muduo 网络库的使用。其设计与实现将有另文讲解。

陈硕的Blog 9万+

fMRI数据处理:从DICOM到NIFTI(上)

哈喽,这里是系列fMRI数据处理文章专栏。包括从核磁拷贝完DICOM格式的文件,到整理数据,检查数据,数据预处理,后续分析等等内容。如果你是一个初学者,特别是心理学或者是刚踏入认知神经科学的小白,那么这个专栏可以帮助你从头到尾完成数据处理直到结果的可视化。如果你已经进入了认知神经科学领域,这里面的内容可能过于细致,并且找不到你想要的答案,不过可以在帖子下留言评论,欢迎大家提供宝贵的意见!如果是医学相关,可能这些内不太准确或专业,谨慎参考!

weixin_44933894的博客 2482

5分钟搞定kkFileView 4.4.0 Docker部署:小白也能上手的完整配置流程

本文提供了一份针对kkFileView 4.4.0版本的Docker部署完整指南。通过使用预构建的Docker镜像,即使是新手也能在5分钟内完成文件预览服务的搭建,涵盖从环境准备、镜像拉取、容器启动到服务验证的全流程,并分享了进阶配置与生产环境优化建议。

mango的博客 526

第十八章:语言工具-inspect:检查现场对象-获取源代码

18.4.6 获取源代码 如果可以得到一个模块的.py文件,则可以使用getsource()和getsourcelines()获取类或方法的原始源代码。 import inspect import example print(inspect.getsource(example.A)) 传入一个类时,输出中会包含这个类的所有方法。 要获取一个方法的源代码,可以将这个方法引用传入getsourc...

编程菜鸟iglesias的博客 552

C# 量子级跨平台开发:用Uno Platform实现Windows、iOS、Android的“量子纠缠”UI同步

墨瑾轩推出编程学习平台,通过XAML的“量子纠缠”技术,实现跨平台开发的高效与一致性。传统方案中,多平台代码重复率高,UI差异大,而量子级方案则通过一套代码构建全平台应用,UI原子化同步,开发效率提升5倍。Uno Platform的“量子纠缠”架构解决了代码碎片化、性能瓶颈和调试难题,实现UI原子化同步、性能提升300%和跨平台数据无缝同步。核心架构包括XAML的跨平台渲染、MVVM的量子叠加态架构、平台差异的量子退相干处理以及性能优化的量子隧穿效应,为开发者提供高效、一致的跨平台开发体验。

java专栏 1165

[Vue CLI 3] vue inspect 的源码设计实现

首先,请记住: 它在新版本的脚手架项目里面非常重要 它有什么用呢? inspect internal webpack config 能快速地在控制台看到对应生成的 webpack 配置对象。 首先它是 vue 的一个扩展命令,在文件 @vue/cli/bin/vue.js 中定义了 command 还是依赖了工具包 commander c...

weixin_33695082的博客 591

VSCode 搭建C/C++编程环境 2025新版图文安装教程(VSCode安装 + C/C++环境搭建 + 运行测试 + 背景图设置)

100%搭建成功,VSCode 搭建C++编程环境 2025新版图文安装教程(VSCode安装+C++环境搭建+运行测试+背景图设置)

Code_流苏:在代码中寻诗意,在实践中觅真知 2974

宽压 DC⇌DC 也能“随心所欲”——全桥 LLC 混合控制硬核拆解

硬件派 vs. 软件派:多电平是“器件堆砌”,混合控制是“算法魔改”。预算紧 → 先搞软件。仿真别嫌烦:PLECS 把两条曲线扫透,切换点、死区、φ 都调到波形平滑再上板。温升留 20 ℃ 余量:车规≥125 ℃,实验室测 105 ℃ 就算危险,别玩极限。

weixin_43199439的博客 928

muduo网络库学习之muduo_http 库涉及到的类

1、http request: request line + header + body (header分为普通报头,请求报头与实体报头) header与body之间有一空行(CRLF) 请求方法有: Get, Post, Head, Put, Delete等 协议版本1.0、1.1 常用请求头 Accept:浏览器可接受的

Meditation 6123

2025美赛E题为农业留出空间(附代码+全保姆教程)Making Room for Agriculture

有机农业的核心在于减少化学投入,促进自然控制和可持续性。变量定义CCC: 作物种群III: 害虫种群PPP: 天然捕食者种群(蝙蝠、鸟类等)BBB: 生物多样性水平(以种类数量表示)SSS: 土壤健康指数(影响植物繁殖与作物生长)EEE: 农业生态系统的整体稳定性。

博客 1495

Python自省(反射)指南

在笔者,也就是我的概念里,自省和反射是一回事,当然其实我并不十分确定一定以及肯定,所以如果这确实是两个不同的概念的话,还请多多指教 :) 转载请注明作者、出处并附上原文链接,多谢!update 2011-3-10: 更正函数的func_globals属性含义。 首先通过一个例子来看一下本文中可能用到的对象和相关概念。 #coding: UTF-8 import sys # 模块...

weixin_30813225的博客 1210

模型实战(16)之StrongSort (OSNET)配合YOLOv5、v7、v8 实现多目标跟踪详解

StrongSort (OSNET)配合YOLOv5、v7、v8 实现多目标跟踪详解

yohnyang的博客 1770

win7 vs2012+wdk8.0 搭建wdf驱动开发环境

开发环境搭建: 系统:win7 x64 工具:vs2012 + WDK8.0 插件:wdfcoinstaller.msi (1)先安装vs2012,再安装wdk8.0,这样在打开vs2012时可以创建windows drivers类型的工程。 注:vs2012不能安装wdk8.1,wdk8.1必须安装在vs2013上 下载链接:http://msdn.microsoft.com/zh-cn/win...

技术联盟 5344

标准库-inspect

import inspect import os #basename求一长串路径中,最后一个路径的名字 binary = os.path.basename(inspect.stack()[-1][1]) print (binary) binary1 = (inspect.stack()) print (binary1) binary2 = (inspect.stack()[-1][1]) p...

you 922

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

muduo的研究目录

发布一个基于 Reactor 模式的 C++ 网络库 https://blog.youkuaiyun.com/solstice/article/details/5848547 – – – – – – – – – – – – – – – – – – – ...

喜欢打篮球的普通人 1298

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

EventLoop再分析之IO线程(29)

EventLoop IO 线程的简单描述 进程(线程)wait/notify pipe socketpair eventfd eventfd 是一个比 pipe 更高效的线程间事件通知机制,一方面它比 pipe 少用一个 file descripor,节省了资源;另一方面,eventfd 的缓冲区管理也简单得多,全部“buffer” 只有定

Riak, Spark, Golang, Erlang, 云存储, 云计算, 数据挖掘 6126

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

http实现源码(40-1)

HttpRequest头文件(包含实现) HttpResquest.h // Copyright 2010, Shuo Chen. All rights reserved. // http://code.google.com/p/muduo/ // // Use of this source code is governed by a BSD-style license // that ca

Riak, Spark, Golang, Erlang, 云存储, 云计算, 数据挖掘 3144
上一篇: http实现源码(40-1)
下一篇: 文件传输服务器(43)
laohan_
博客等级 码龄15年 112粉丝 224原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值