2014年11月12日
摘要: 一年前就打算学Python了,折腾来折腾去也一直没有用熟练,主要是类那一块不熟,昨天用Python写了几个网络编程的示例,感觉一下子迈进了很多。这几天把学习Python的笔记整理一下,内容尽量简洁。 下面这个例子演示类的基本使用: # coding:utf-8 class Test(): s = '这是一个静态变量' def __init__(self): ... 阅读全文
posted @ 2014-11-12 14:38 inevermore 阅读(603) 评论(0) 推荐(1) 编辑
  2014年10月27日
摘要: 本文无太多内容,主要是几个前面提到过的注意点: 一是epoll的fd需要重新装填。我们将tcp_connection_t的指针保存在数组中,所以我们以这个数组为依据,重新装填fd的监听事件。 //重新装填epoll内fd的监听事件 int i; for(i = 0; i buffer_)) event |= kWri... 阅读全文
posted @ 2014-10-27 20:46 inevermore 阅读(909) 评论(0) 推荐(0) 编辑
摘要: 使用poll与epoll的区别主要在于: poll可以每次重新装填fd数组,但是epoll的fd是一开始就加入了,不可能每次都重新加入 于是采用这种策略: epoll除了listenfd一开始就监听read事件,其他的客户fd加入epoll时,监听的事件都为空。 然后在每次epoll_wait之前,使用epoll_ctl重新设置fd的监听事件。 所以这部分的代码如下:... 阅读全文
posted @ 2014-10-27 20:37 inevermore 阅读(3179) 评论(0) 推荐(1) 编辑
摘要: 关于poll模型监听的事件以及返回事件,我们定义宏如下: #define kReadEvent (POLLIN | POLLPRI) #define kWriteEvent (POLLOUT | POLLWRBAND) #define kReadREvent (POLLIN | POLLPRI | POLLRDHUP) #define kWriteREvent (POLLOUT) 前面... 阅读全文
posted @ 2014-10-27 20:15 inevermore 阅读(1086) 评论(0) 推荐(0) 编辑
  2014年10月24日
摘要: 前面几节我们讨论了非阻塞IO的基本概念、Buffer的设计以及非阻塞connect的实现,现在我们使用它们来完成客户端的编写。 我们在http://www.cnblogs.com/inevermore/p/4049165.html中提出过,客户端需要监听stdin、stdout和sockfd。 这里需要注意的是 只有缓冲区可写的时候,才去监听sockfd和stdin的读事件。 过... 阅读全文
posted @ 2014-10-24 20:44 inevermore 阅读(765) 评论(0) 推荐(0) 编辑
摘要: 我们为客户端的编写再做一些工作。 这次我们使用非阻塞IO实现connect函数。 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 非阻塞IO有以下用处: 1.将三次握手的处理过程生下来,处理其他事情。 2.使用这个同时建立多个连接。 3.实现超时connect功能,本... 阅读全文
posted @ 2014-10-24 20:09 inevermore 阅读(1531) 评论(0) 推荐(0) 编辑
摘要: 本文我们来实现回射服务器的Buffer。 Buffer的实现 上节提到了非阻塞IO必须具备Buffer。再次将Buffer的设计描述一下: 这里必须补充一点,writeIndex指向空闲空间的第一个位置。 这里有三个重要的不变式: 1. 0 #define BUFFER_SIZE 1024 typedef struct { char buf_[BUFF... 阅读全文
posted @ 2014-10-24 15:36 inevermore 阅读(1613) 评论(0) 推荐(0) 编辑
  2014年10月23日
摘要: 上文描述了最简易的非阻塞IO,采用的是轮询的方式,这节我们使用IO复用模型。 阻塞IO 过去我们使用IO复用与阻塞IO结合的时候,IO复用模型起到的作用是并发监听多个fd。 以简单的回射服务器为例,我们只监听了某fd是否可读,一旦fd有数据,我们立刻read,然后将其write给对方。 在阻塞IO里面,我们总是认为fd是可写的。因为即使底层的IO缓冲区已满,稍微等待片刻即可。这... 阅读全文
posted @ 2014-10-23 17:05 inevermore 阅读(1651) 评论(0) 推荐(0) 编辑
摘要: 非阻塞IO是相对于传统的阻塞IO而言的。 我们首先需要搞清楚,什么是阻塞IO。APUE指出,系统调用分为两类,低速系统调用和其他,其中低速系统调用是可能会使进程永远阻塞的一类系统调用。但是与磁盘IO有关的系统调用是个例外。 我们以read和write为例,read函数读取stdin,如果是阻塞IO,那么: 如果我们不输入数据,那么read函数会一直阻塞,一直到我们输入数据为止。 如... 阅读全文
posted @ 2014-10-23 11:27 inevermore 阅读(2454) 评论(0) 推荐(1) 编辑
  2014年10月22日
摘要: readn 在Linux中,read的声明为: ssize_t read(int fd, void *buf, size_t count); 它的返回值有以下情形: 1.大于0,代表成功读取的字节数 2.等于0,代表读取到了EOF,一般是对方关闭了socket的写端或者直接close 3.小于0,出现错误。 我们编写一个readn函数,声明与read... 阅读全文
posted @ 2014-10-22 22:11 inevermore 阅读(807) 评论(0) 推荐(0) 编辑
摘要: 本文的主要目的是将server套接字和client套接字的获取,做一个简易的封装,使用C语言完成。 tcp_server 服务器端fd的获取主要分为以下几步: 1.创建socket,这一步仅仅创建一个socket,没有任何特性的属性。 2.绑定网卡和port,一块主机可能有多块网卡,如果我们使用INADDR_ANY,意味着后面接受的TCP连接可以绑定在任意一块网卡... 阅读全文
posted @ 2014-10-22 21:31 inevermore 阅读(2541) 评论(0) 推荐(2) 编辑
  2014年10月20日
摘要: 读本文之前,请务必阅读: 使用C++11的function/bind组件封装Thread以及回调函数的使用 Linux组件封装(五)一个生产者消费者问题示例 线程池本质上是一个生产者消费者模型,所以请熟悉这篇文章:Linux组件封装(五)一个生产者消费者问题示例。 在ThreadPool中,物品为计算任务,消费者为pool内的线程,而生产者则是调用线程池的每个函数。 搞清了这一点,... 阅读全文
posted @ 2014-10-20 20:56 inevermore 阅读(4940) 评论(0) 推荐(0) 编辑
摘要: 之前在http://www.cnblogs.com/inevermore/p/4008572.html中采用面向对象的方式,封装了Posix的线程,那里采用的是虚函数+继承的方式,用户通过重写Thread基类的run方法,传入自己的用户逻辑。 现在我们采用C++11的function,将函数作为Thread类的成员,用户只需要将function对象传入线程即可,所以Thread的声明中,应... 阅读全文
posted @ 2014-10-20 20:00 inevermore 阅读(8500) 评论(0) 推荐(1) 编辑
  2014年10月19日
摘要: 测试#include #include #include using namespacestd;class Test{public: Test() { cout ptr(new Test); return 0;} 阅读全文
posted @ 2014-10-19 01:41 inevermore 阅读(193) 评论(0) 推荐(0) 编辑
  2014年10月17日
摘要: 在C++98中,可以使用函数指针,调用函数,可以参考之前的一篇文章:类的成员函数指针和mem_fun适配器的用法。 简单的函数调用 对于函数: void foo(const string &s) { cout f = &foo; f("bar"); 再看另外一个例子: void foo(int i, double d) { cout f =... 阅读全文
posted @ 2014-10-17 22:12 inevermore 阅读(831) 评论(0) 推荐(1) 编辑
摘要: 前面两节,说明了右值引用和它的作用。下面通过一个string类的编写,来说明右值引用的使用。 相对于C++98,主要是多了移动构造函数和移动赋值运算符。 先给出一个简要的声明: class String { public: String(); String(const char *s); //转化语义 String(const String &s); S... 阅读全文
posted @ 2014-10-17 20:36 inevermore 阅读(849) 评论(0) 推荐(0) 编辑
  2014年10月16日
摘要: 上节我们提出了右值引用,可以用来区分右值,那么这有什么用处? 问题来源 我们先看一个C++中被人诟病已久的问题: 我把某文件的内容读取到vector中,用函数如何封装? 大部分人的做法是: void readFile(const string &filename, vector &words) { words.clear(); //read XXXXX ... 阅读全文
posted @ 2014-10-16 22:51 inevermore 阅读(498) 评论(0) 推荐(0) 编辑
摘要: 移动语义 阅读全文
posted @ 2014-10-16 21:31 inevermore 阅读(626) 评论(0) 推荐(0) 编辑
  2014年10月9日
摘要: 本文系原创,转载请注明:http://www.cnblogs.com/inevermore/p/4014577.html 根据维基百科,对单例模式的描述是: 确保一个类只有一个实例,并提供对该实例的全局访问。 从这段话,我们可以得出单例模式的最重要特点: 一个类最多只有一个对象 单线程环境 对于一个普通的类,我们可以任意的生成对象,所以我们为了避... 阅读全文
posted @ 2014-10-09 22:05 inevermore 阅读(1084) 评论(0) 推荐(0) 编辑
摘要: 先来看一个最简单的函数: void foo(int a) { cout *pFunc2)(7865); 此时的使用方式是正确的。 那么bar函数是static函数,它具有什么特点呢? void (*pFunc)(int) = &Foo::bar; pFunc(123); 我们发现,static函数和自由函数的指针类型一致。 既然foo含有一个隐式参... 阅读全文
posted @ 2014-10-09 21:08 inevermore 阅读(804) 评论(0) 推荐(0) 编辑