构造多协议服务器
来源:互联网 发布:windows pe 硬盘版 编辑:程序博客网 时间:2024/06/06 05:21
这次我们讨论多协议服务器 设计初衷: 每种协议使用一个服务器会使代码重复,另外,UDP和TCP都是用相同的基本算法来计算响应,他们都包含执行计算所需要的代码,这样的话管理程序就变得冗长和乏味。 设计: 一个多协议服务器由一个单执行线程构成,这个线程既可以在TCP也可以在UDP上使用异步I/O来处理通信。服务器最初打开2个套接字,一个UDP,一个TCP。接着服务器使用异步I/O等待两个套接字之一就绪。如果TCPsocket就绪,说明是一个TCP连接,使用accept获得新的连接,并在这个链接上与客户通信。如果UDPsocket就绪,说明客户以UDP数据报形式发来一个请求。服务器就用recvfrom读取该请求,并记录此发送者的端点地址。当服务器计算出响应后,就调用sendto将响应发回给客户。 进程结构: 代码: extern int errno; int daytime(char buf[]); int errexit(const char *format, ...); int passiveTCP(const char *service, int qlen); int passiveUDP(const char *service); #define MAX(x, y) ((x) > (y) ? (x) : (y)) #define QLEN 32 #define LINELEN 128 /*------------------------------------------------------------------------ * main - Iterative server for DAYTIME service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char *service = "daytime"; /* service name or port number */ char buf[LINELEN+1]; /* buffer for one line of text */ struct sockaddr_in fsin; /* the request from address */ unsigned int alen; /* from-address length */ int tsock; /* TCP master socket */ int usock; /* UDP socket */ int nfds; fd_set rfds; /* readable file de script ors */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: daytimed [port]/n"); } tsock = passiveTCP(service, QLEN); usock = passiveUDP(service); 服务器创建主套接字后,便准备使用select,以便等待其中之一或两者同时I/O准备就绪。首先,他把变量nfds设置为两个套接字中较大的那个,以此作为描述符比特屏蔽码的索引,他还把比特屏蔽码(遍历那个rfds)清零。接着,服务器进入一个无限循环之中。在每次循环中,使用宏FD_SET构造比特屏蔽码,其置1的比特对应于两个主套接字的描述符。接着使用select等待这二者之一的输入激活。 nfds = MAX(tsock, usock) + 1; /* bit number of max fd */ FD_ZERO(&rfds); while (1) { FD_SET(tsock, &rfds); FD_SET(usock, &rfds); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) errexit("select error: %s/n", strerror(errno)); if (FD_ISSET(tsock, &rfds)) { int ssock; /* TCP slave socket */ alen = sizeof(fsin); ssock = accept(tsock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept failed: %s/n", strerror(errno)); daytime(buf); (void) write(ssock, buf, strlen(buf)); (void) close(ssock); } if (FD_ISSET(usock, &rfds)) { alen = sizeof(fsin); if (recvfrom(usock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) < 0) errexit("recvfrom: %s/n", strerror(errno)); daytime(buf); (void) sendto(usock, buf, strlen(buf), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } } } 这段代码很简单,他们都是用单线程来解决并发问题,基本上就是循环的无连接服务器+循环的面向连接的服务器的集合版本。 这里有个小的调整就是daytime函数,因为他要既要适合tcp也要适合udp,由于udp是不用write函数,而是拿到了数据之后直接sendto,而tcp拿到数据之后先要write然后再关闭连接,所以daytime函数的设计更显得一般化。Time函数返回一个时间。 /*------------------------------------------------------------------------ * daytime - fill the given buffer with the time of day *------------------------------------------------------------------------ */ int daytime(char buf[]) { char *ctime(); time_t now; (void) time(&now); sprintf(buf, "%s", ctime(&now)); }
- 构造多协议服务器
- 多任务处理:服务器协议
- linux socket编程 多协议服务器例子
- 服务器客户端构造流程
- 构造Linux流媒体服务器
- 构造Liunx流媒体服务器
- FTP服务器的构造
- 构造协议报文、自定制协议方法
- 03-构造可靠数据传输协议
- 文件传输协议的服务器
- SQL服务器引擎---协议
- 服务器使用git协议
- MySQL客户端/服务器协议
- 邮件服务器端口协议
- DNS服务器使用协议
- 时间服务器通讯协议
- Tomcat服务器&http协议
- Git : SSH 协议服务器
- 关于BIOS加载BOOT.S的经典解答
- volatile
- error LNK2019: unresolved external symbol "public 错误的出现原因.
- js线程
- 设置串口读写超时
- 构造多协议服务器
- WebFOCUS展现案例(参数化报表、仪表盘、Gis集成、移动应用。。。)
- 归并排序算法
- Apache的rewrite的重写相关的参数
- Oracle中最易忽视的两个重要进程
- research on btrfs
- shell脚本编写
- DB2命令大全
- I'm Dead