﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-实验室宅男的一亩三分地-随笔分类-linux编程</title><link>http://www.cppblog.com/whspecial/category/20720.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 30 Oct 2013 16:42:50 GMT</lastBuildDate><pubDate>Wed, 30 Oct 2013 16:42:50 GMT</pubDate><ttl>60</ttl><item><title>UNIX网络编程读书笔记</title><link>http://www.cppblog.com/whspecial/archive/2013/10/31/204011.html</link><dc:creator>whspecial</dc:creator><author>whspecial</author><pubDate>Wed, 30 Oct 2013 16:32:00 GMT</pubDate><guid>http://www.cppblog.com/whspecial/archive/2013/10/31/204011.html</guid><wfw:comment>http://www.cppblog.com/whspecial/comments/204011.html</wfw:comment><comments>http://www.cppblog.com/whspecial/archive/2013/10/31/204011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/whspecial/comments/commentRss/204011.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/whspecial/services/trackbacks/204011.html</trackback:ping><description><![CDATA[&nbsp; &nbsp;这一段在看《unix网络编程》，回顾之前做项目用到的一些东西，在这里总结一下：<br /><br />&nbsp;<strong> &nbsp;(1)TCP套接口编程</strong><br />&nbsp; &nbsp;这里介绍各个接口函数：<br />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">1 文件描述符</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－socket(int domain, int type, int protocol); //生成文件描述符</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－bind(int sockfd, struct sockaddr *my_addr, int addrlen); //将本地的一个端口绑定到fd上，一般只需要在server端</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">2 服务端</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－listen(int sockfd, int backlog); //有两个作用：1,将主动套接口变为被动套接口;2,设置最大连接数backlog</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－accept(int sockfd, void *addr, int *addrlen); //为建立好的连接生成一个新的fd</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">3</span><span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">&nbsp;客户端</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－connect(int sockfd, struct sockaddr *serv_addr, int addrlen); //进行socket连接</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">4 通信</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－send(int sockfd, const void *msg, int len, unsigned int flags); //发送请求</span><br style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;" />&nbsp; &nbsp;<span style="font-family: Arial; line-height: 24px; background-color: #ffffff;">－recv(int sockfd, void *buf, int len, unsigned int flags); //接收请求</span><span style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;"><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/whspecial/20120130150030502.png" width="654" height="672" alt="" /></span><br /><br />&nbsp;<strong> &nbsp;(2)I/O多路复用</strong><br />&nbsp;&nbsp;&nbsp;I/O多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取，它就通知该进程。按照《UNIX网络编程》的说法，I/O多路复用用于以下三种情况：<br /><span>&nbsp; &nbsp;a)</span><span style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;">一个TCP服务器既要处理监听套接口，又要处理已连接套接口；<br /></span><span>&nbsp; &nbsp;b)</span><span style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;">一个服务器既要处理TCP，又要处理UDP；<br /></span><span>&nbsp; &nbsp;c)</span><span style="font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;">当客户端处理多个描述字（比如处理交互式输入和网络套接口）</span><span style="color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; line-height: 24px; background-color: #ffffff;"><br /></span>&nbsp; &nbsp;目前被广泛使用的是select和epoll：<br />&nbsp; &nbsp;2.1,select<br />&nbsp;&nbsp;&nbsp;int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout)<br />&nbsp; &nbsp;第一个参数指定最大的fd数目，中间三个分别是被监控的读、写、异常的fd集，最后一个是超时时间。select函数会阻塞等待，直到监控的fd集中有fd就绪，或者已经超时。<br />&nbsp; &nbsp;2.2,epoll<br />&nbsp; &nbsp;epoll相比于select，主要的好处在于它不像select一样去轮询fd集，而是由内核去触发；另外它支持更大的fd个数<br /><br />&nbsp;<strong> &nbsp;(3)网络服务器模型</strong><br />&nbsp; &nbsp;其实网络服务器模型还是比较复杂的，有一篇比较经典的文章叫做c10K problem，链接如下：<a href="http://www.kegel.com/c10k.html">http://www.kegel.com/c10k.html</a><br />&nbsp; &nbsp;这里记录的是很简单的几种多线程TCP服务器模型，顺便可以比较下：<br />&nbsp; &nbsp;2.1 主线程accept，为每个client创建一个线程<br />&nbsp; &nbsp;2.2 使用线程池，全部accept，当有连接来的时候其中某个线程进行处理<br />&nbsp; &nbsp;2.3 使用线程池，主线程accept，当有连接来的时候主线程将其放入队列，由工作线程进行处理（生产者-消费者模型）<br />&nbsp; &nbsp;1方案过于频繁地进行线程创建销毁，2方案在一个连接过来时会带来惊群现象，3方案会比前两个方案要好一些。<img src ="http://www.cppblog.com/whspecial/aggbug/204011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/whspecial/" target="_blank">whspecial</a> 2013-10-31 00:32 <a href="http://www.cppblog.com/whspecial/archive/2013/10/31/204011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>