随笔分类 -  网络编程

摘要:linux socket使用16bit无符号整型表示端口号,最大到65535。关于端口号,有一个经典的误解就是,因为端口号有限,所以一个客户端最多建立65536个socket连接,但实际上并不是这么回事,端口是可以复用的。 一个socket连接是一个[srcip, srcport, destip, destport]组成的四元组,如果再算上协议(tcp、udp、rawsocket等)就是五... 阅读全文
posted @ 2013-04-19 14:14 ydzhang 阅读(2926) 评论(0) 推荐(0)
摘要:VISIO原图:rpc流程图.rar 管理员在2009年8月13日编辑了该文章文章。 --> --> 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(123) 评论(0) 推荐(0)
摘要:http协议 网络通信领域,协议是指通信双方约定的规则,彼此按照规则交互,才能理解对方。http是超文本传输协议,之所以需要这样一个规则,是因为现实世界中,C/S请求应答模式的应用占据绝大部分,如果每一种服务都定义自己的格式,世界就会开始变的混乱了,每个人在开发服务器的时候都需要开发对应的客户端,而这个工作显然是不必要的。而为什么选择http而不是其他的规则呢,因为其简单、无状态,能满足应用需求... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(235) 评论(0) 推荐(0)
摘要:网络服务器的实现不外乎两种情况,一是为某个业务单端开发服务器,二是实现通用网络服务器框架,前者的设计可能很大程度的受业务需求的影响,而后者则要保证简单易用,稳定服务,最好还有不错的性能。 服务器框架的优势在于让使用者快速的进行开发,只需要做很少的事情即可完成服务器的开发。在整个服务模型中,只有对请求任务的处理是预先不可知的,其他的逻辑基本上是固定的,故在实现框架时,将实际的处理部分以回调的形... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(164) 评论(0) 推荐(0)
摘要:循环read(write) 在网络应用程序中,通常需要重复的调用read/write来读取到指定数量的数据,如下例: int wrapper_read(int fd, char *buf, int size) { int ridx = 0; int rlen = 0; while(ridx < size) { rlen = read(fd, buf + ridx, size – ri... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(278) 评论(0) 推荐(0)
摘要:关于listen的backup参数 listen的第二个参数,在网上有各种版本的解释,有人说是三次握手成功等待被accept的请求队列长度,有人说是尚未成功建立连接的队列长度,有人说是二者队列长度之和。 #man listen # man tcp 从man手册可以发现:从linux 2.2开始,backlog是指已经建立连接等待被accept的队列长度,而未成功建立连接的队列长度由tc... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(203) 评论(0) 推荐(0)
摘要:线程池服务模型是single thread 与 request per thread两种模型的折中方案,其在实现时通常需要借助任务队列,主线程往任务队列尾添加任务,线程池中的服务线程不断从任务队列头取任务并服务,如下图所示: 对于主线程和服务线程来说,任务队列是临界资源,需要加锁进行保护。主线程往任务队列添加任务时需要加锁,服务线程从任务队列取任务也许加锁,当服务线程发现任... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(162) 评论(0) 推荐(0)
摘要:多线程在网络编程中作用重大,由于创建/销毁线程、线程间通信的开销小,目前很多网络服务器都是用多线程(线程池)的模式对外提供服务。linux上开发多线程程序多使用pthread库,本文主要讨论使用C++封装pthread库时可能出现的问题。 封装pthread库主要有两种思路,第一种是简单的封装接口,如下所示: class simple_thread_t { public: int star... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(195) 评论(0) 推荐(0)
摘要:linux提供了select、poll、epoll接口来实现IO复用,三者的原型如下所示,本文从参数、实现、性能等方面对三者进行对比。 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int poll(struct pollfd *fds,... 阅读全文
posted @ 2013-04-19 14:12 ydzhang 阅读(173) 评论(0) 推荐(0)
摘要:libevent提供一种当特定事件发生、超时或信号到达时执行回调函数的机制,看了libevent的代码,里面包含了对普通事件、超时事件的处理;libevent-0.1(2000年发布)使用select来进行IO轮询,最新的libevent版本使用epoll。(http://monkey.org/~provos/libevent/) libevent的实现框架(三个主体 — 事件、队列、处理): ... 阅读全文
posted @ 2013-04-19 14:11 ydzhang 阅读(435) 评论(0) 推荐(0)
摘要:micro_httpd是一个轻量级的http服务器 (http://www.acme.com/software/micro_httpd/),micro_httpd从xinetd运行,性能较差,但对于负载较小的网站,micro_httpd是能胜任的,其实现了http服务器的一些基本特征功能: 1. ..文件名探测以保证安全; 2. 常用MIME类型识别; 3. Trailing-slash重定向;... 阅读全文
posted @ 2013-04-19 14:11 ydzhang 阅读(1109) 评论(0) 推荐(0)
摘要:Protocol buffer是google开源的又一利器,主要用于结构化数据存储与数据交换,类似于XML,但相比XML,它更小、更快、也更简单,只需使用protobuf对数据结构进行一次描述,即可利用各种不同的语言(包括C++、java、python等,同时还包括很多种语言的绑定插件)从各种不同的数据流(文件、字符串流等)对结构化数据轻松读写。但由于其使用二进制存储,相比XML,其可读性差。 ... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(4195) 评论(0) 推荐(0)
摘要:getaddrinfo是在gethostbyname系列函数不支持Ipv6的情况下逐渐催生的,其能够处理名字到地址以及服务到端口这两种转换,返回一个sockaddr结构的链表,这些sockaddr地址结构随后可有套接口函数(socket、bind、connect、listen等)直接调用,将协议相关性隐藏在该函数内部。应该尽量选择使用getaddrinfo函数代替之前的getxx函数族,就像应该使... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(1815) 评论(0) 推荐(1)
摘要:实线:表示客户的正常状态转换 虚线:表示服务器的正常状态装换 应用:表示状态转换在应用进程发起操作时发生 接受:表示状态转换在接受到分节时发生 发送:表示这个转换发送什么 三次握手建立连接 服务器调用socket、bind、listen来完成,即执行被动打开,准备好接受外来的请求。 1.客户端发调用connect发送SYN分节(同步),它告诉服务器客户将在连接中发送的数据的初始... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(265) 评论(0) 推荐(0)
摘要:xinetd是inetd超级服务器的升级版,相当于inetd + tcp wrapper,将服务管理与访问控制结合在一起。在介绍inetd之前,先看一个xinetd的实例(我的机器上只有xinetd,关于inetd的配置参考UNP 325页)。 xinet配置实例 为xinetd添加myecho服务(将客户端发来的请求消息回送给客户端)。 1. 在/etc/services中添加myec... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(349) 评论(0) 推荐(0)
摘要:1. 重用已使用的地址 问题描述:在刚刚关闭了测试程序后,再启动服务器时提示bind失败,返回错误EADDRINUSE。 原因分析:套接字(主动关闭一端)在关闭套接字后会停留在TIME_WAIT状态一端时间,由于我在同一机器上同时运行客户端与服务器,故服务器在重新启动执行bind时,可能上次关闭连接还没有完成,连接依然存在,故bind失败。通过设置套接口的SO_REUSEADDR可重用已绑定的... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(150) 评论(0) 推荐(0)
摘要:1. read系统调用 测试程序:客户端向服务器端(tcp)发送一个”hello”字符串,服务器端读取并echo到客户端。 服务器端主要代码: char buf[4096]; int r = tcp_readn(sock, buf, 4096); int w = tcp_writen(sock, buf, r); 客户端主要代码: char buf[4096]; int w... 阅读全文
posted @ 2013-04-19 14:10 ydzhang 阅读(339) 评论(0) 推荐(0)
摘要:在项目中遇到一个问题,当客户端通过SUN RPC进行远程过程调用时,服务器如何获取调用方的IP地址,由于RPC是socket的封装,在send/recv的调用中都能获取数据包的源IP地址,故RPC肯定又能提供这样的接口。 最开始的需求源于DNFS的存储节点周期性的向元数据服务器发送心跳信息,当收到心跳信息后,服务器需要辨别心跳信息来自哪一个存储节点,WCW师兄的方法是在调用参数中增加IP地址... 阅读全文
posted @ 2013-04-19 14:07 ydzhang 阅读(2068) 评论(0) 推荐(0)
摘要:void square_prog_2(char *host) { CLIENT *clnt; enum clnt_stat retval_1; square_out result_1; square_in squareproc_2_arg; squareproc_2_arg.arg = 11; clnt = clnt_create (host, square_prog, square... 阅读全文
posted @ 2013-04-19 14:06 ydzhang 阅读(783) 评论(0) 推荐(0)
摘要:对于rpc说明书文件test.x,其中定义服务器过程以及他们的参数和结果。 使用rpcgen必须要生成的几个文件: rpcgen –C -M test.x //-C生成ANSI C的代码, -M test.h:过程及其参数的说明 tes_xdr.c: 用于rpc外部数据表示 test_clnt.c :客户端存根 test_svc.c : 服务器存根 对于说明书文件test.x(至于说明书文... 阅读全文
posted @ 2013-04-19 14:05 ydzhang 阅读(646) 评论(0) 推荐(0)