套接字和在标准I|O之间的转化

用标准IO代替read和write函数的TCP回射服务器重编

tcp服务器端口,代码片段如下:

文件:dg_echo_stdio01.c

#include "unp.h"

void str_echo(int sockfd)
{
    char buf[MAXLINE];
    FILE *pread, *pwrite;
    pread = Fdopen(sockfd, "r");
    pwrite = Fdopen(sockfd, "w");
    while(Fgets(buf, MAXLINE, pread) != NULL){
        Fputs(buf, pwrite);
    }
}


主函数main中, 核心处理程序伪代码如下:

clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
    if (errno == EINTR)
        continue;       /* back to for() */
    else
        err_sys("accept error");
}

if ( (childpid = Fork()) == 0) {    /* child process */
    Close(listenfd);    /* close listening socket */
    str_echo(connfd);   /* process the request */
    exit(0);
}
Close(connfd);          /* parent closes connected socket */



服务器子进程建立连接, 如以上代码片段如所示,为子进程处理, 请求应答的核心代码。

代码运行结果如下:


步骤如下:

1)、当我们键入第一行输入文本, 他被发送到服务器

2)、服务器用fgets读入本行, 然后再fputs回射本行。

3)、因为服务器的标准io,都是全缓冲。所以数据被服务器回射到标准io的缓冲区中,但是并没有把该缓冲的数据写好描述符中区去,因为该缓冲的数据未满。

4)、服务器再次fgets读入本行, 还用fputs回射本行。

5)、数据再次被回射到标准IO上面,但是因为缓冲区未满,所以不得把数据写到描述符中中去。

6)、第三行数据如上所示。

7)、当我们键入EOF数据的时候, 至使我们调用shutdown,从而发送了FIN分节到服务器。

8)、当服务器TCP接受到了FIN分节, Fgets读入,并且返回了一个空指针

9)、子进程调用exit函数终止。因为exit退出,之前写入到标准IO缓冲区里面的数据将会被输出(exit详细详解见unix环境编程)

10)、服务器子进程终止,三行文本数据将会通过套接字描述符回射到客服端。


标准IO执行的三类缓冲

1)、完全缓冲:只有当缓冲区满, 进程显示调用fflush,或者进程调用exit终止自身的情况下才会发生标准I|O。标准IO缓冲区通常的大小是8192

2)、行缓冲:碰到一个换行符,进程显示调用fflush,或者进程调用exit终止自身等情况下才会发生标准I|O。

3)、不缓冲:意味着每次调用标准I|O函数都发生I|O


标准I|O函数库的大多数unix实现规则如下

1)、标准错误输出总是不缓冲的

2)、标准输出和标准出入都是完全缓冲,除非他们指代终端设备(这种情况下是行缓冲)

3)、所有的io流都是完全缓冲,除非他们指代终端设备(这种情况下是行缓冲)


根据以上的试验和描述,和Nagle算法的交付分析可以得出结论:在套接字上要避免使用标准I|O函数库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值