用TCP/TP进行网际互连(7)
———— 支持多协议多服务的服务器设计和实现
融合之前实现的各种协议与服务的代码,实现一个支持多协议多服务的服务器。
1、实现过程
- 服务器:
- errexit.c、passivesock.c、passiveTCP.c、passiveUDP.c分别是之前对相应过程代码的封装。
- superd.c :在初始化数据结构并为它所提供的每个服务打开套接字之后,服务器主程序便进入了无限循环。每一次循环都调用select,以便等待各套接字中的某个准备就绪。当请求到达时,select就返回。
- sv_funcs.c :是一些提供的服务的具体实现,包含TCPechod(int), TCPchargend(int), TCPdaytimed(int), TCPtimed(int), UDPechod(int), UDPtimed(int);
这里只贴一下主要代码,全部代码已上传github,有兴趣可以拿来看一下:
https://github.com/KevinBetterQ/Network-programming/tree/master/All/S
//superd.c :
int main(int argc, char *argv[])
{
struct service *psv, /* service table pointer */
*fd2sv[NOFILE]; /* map fd to service pointer */
int fd, nfds;
fd_set afds, rfds; /* readable file descriptors */
switch (argc) {
case 1:
break;
case 2:
portbase = (unsigned short) atoi(argv[1]);
break;
default:
errexit("usage: superd [portbase]\n");
}
nfds = 0;
FD_ZERO(&afds);
for (psv = &svent[0]; psv->sv_name; ++psv) {
if (psv->sv_useTCP)
psv->sv_sock = passiveTCP(psv->sv_name, QLEN);
else
psv->sv_sock = passiveUDP(psv->sv_name);
fd2sv[psv->sv_sock] = psv;
nfds = MAX(psv->sv_sock+1, nfds);
FD_SET(psv->sv_sock, &afds);
}
(void) signal(SIGCHLD, reaper);
while (1) {
memcpy(&rfds, &afds, sizeof(rfds));
if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0,
(struct timeval *)0) < 0) {
if (errno == EINTR)
continue;
errexit("select error: %s\n", strerror(errno));
}
for (fd=0; fd<nfds; ++fd)