沾化城北工业园管委会:构造循环的面向连接的服务器

来源:百度文库 编辑:中财网 时间:2024/04/30 14:24:55

“循环的面向连接”的服务器

优缺点:

面向连接的服务器的好处在于易于编程。特别是因为传输协议自动处理分组丢失和交付失序问题,而服务器就不需要处理这些问题了。但是面向连接服务器要求对每个连接都有一个单独的套接字,而无连接的设计则允许从一个套接字上与多个主机通信。最重要的缺点是tcp在空闲的连接上根本不发送任何分组。

算法:

1,  创建套接字并将其绑定到它所提供服务的熟知端口上。

2,  将该端口设置为被动模式,使其准备为服务器所用。

3,  从该套接字上接受下一个连接请求,获得该联检的新的套接字。

4,  重复的读取来自客户的请求,构造响应,按照应用协议向客户发回响应。

5,  当与某个特定客户完成交互时,关闭连接,返回步骤3以接受新的连接。

 

Int main(int argc, char *argv[])

{

       struct      sockaddr_in fsin;    /* the from address of a client      */

       char *service = "daytime";     /* service name or port number    */

       int    msock, ssock;              /* master & slave sockets     */

       unsigned int    alen;        /* from-address length          */

 

       switch (argc) {

       case 1:

              break;

       case 2:

              service = argv[1];

              break;

       default:

              errexit("usage: TCPdaytimed [port]/n");

       }

 

       msock = passiveTCP(service, QLEN);

之前的代码和循环的无连接的服务器代码基本相同。

进入无限循环之后,首先服务器调用accept从主套接字获得下一个连接,而accept函数会一直阻塞,直到一个链接到达,并且该函数相当于强制执行了一个三次握手,一旦握手完成,并且系统已为传入连接分配了一个新套接字,accept调用将返回新套接字的描述符。

       while (1) {

              alen = sizeof(fsin);

              ssock = accept(msock, (struct sockaddr *)&fsin, &alen);   //分配临时套接字

              if (ssock < 0)

                     errexit("accept failed: %s/n", strerror(errno));

              TCPdaytimed(ssock);  

              (void) close(ssock);

       }

}

之前的close()从容关闭。Tcp的从容关闭的定义意味着close调用可能不立即返回---在服务器上tcp从客户的tcp收到答复前,将一直阻塞。一旦客户确认他收到了所有数据和终止连接的请求,close调用返回。

每次在新的连接到达时,服务器调用TCPdaytimed对他进行处理。函数time和ctime为核心,time返回一个32比特整数,以此给出当前时间。库函数ctime带有一个整形参数,该函数返回一个含有格式化的时间和日期的ascII字符串地址,一旦服务器获得用ASCII字符串表示的时间和日期,调用write将字符串通过tcp连接发送给客户。

/*------------------------------------------------------------------------

 * TCPdaytimed - do TCP DAYTIME protocol

 *------------------------------------------------------------------------

 */

void

TCPdaytimed(int fd)

{

       char *pts;                     /* pointer to time string  */

       time_t     now;                     /* current time                     */

       char *ctime();

 

       (void) time(&now);

       pts = ctime(&now);

       (void) write(fd, pts, strlen(pts));

}