Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。下面详细介绍一下!

Select的函数格式(我所说的是Unix系统下的伯克利socket编程,和windows下的有区别,一会儿说明):

先说明两个结构体:

第一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。fd_set集合可以通过一些宏由人为来操作,比如清空集合FD_ZERO(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set *),将一个给定的文件描述符从集合中删除FD_CLR(int ,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。一会儿举例说明。

第二,struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。

阅读全文

原文地址: http://scotdoyle.com/python-epoll-howto.html

文章里面的代码可以 点击这里下载.

<p>
  第一个例子是一个简单的python3.0版本的服务器代码, 监听8080端口的http请求, 打印结果到命令行, 回应http response给客户端.
</p>

<ul>
  <li>
    行 9: 建立服务器的socket
  </li>
  <li>
    行 10: 允许11行的bind()操作, 即使其他程序也在监听同样的端口. 不然的话, 这个程序只能在其他程序停止使用这个端口之后的1到2分钟后才能执行.
  </li>
  <li>
    行 11: 绑定socket到这台机器上所有IPv4地址上的8080端口.
  </li>
  <li>
    行 12: 告诉服务器开始响应从客户端过来的连接请求.
  </li>
  <li>
    行 14: 程序会一直停在这里, 直到建立了一个连接. 这个时候, 服务器socket会建立一个新的socket, 用来和客户端通讯. 这个新的socket是accept()的返回值, address对象标示了客户端的IP地址和端口.
  </li>
  <li>
    行 15-17: 接收数据, 直到一个完整的http请求被接收完毕. <a href="http://www.jmarshall.com/easy/http/">这是一个简单的http服务器实现</a>.
  </li>
  <li>
    行 18: 为了方便验证, 打印客户端过来的请求到命令行.
  </li>
  <li>
    行 19: 发送回应.
  </li>
  <li>
    行 20-22: 关闭连接, 以及服务器的监听socket.
  </li>
</ul>

<p>

阅读全文

作者的图片

DigDeeply

Technology Stack: Golang/PHP/Openresty, and so on…

Web Development Engineer

Beijing China