某公司的一道试题

来源:互联网 发布:无肩带内衣 知乎 编辑:程序博客网 时间:2024/05/01 07:27

该代码实现了一个客户端回射程序,即从用户获得输入的一行文本,发给服务器,当接到服务器的应答信息后,打印该信息。请阅读代码回答问题。
#include    "unp.h"   // 可认为这行是正确的,包含了所有以下函数用到的头文件。
 
Int main(int argc, char **argv)
{
    int sockfd;
    struct sockaddr_in servaddr;
    if (argc != 2)
        err_quit("usage: tcpcli ");
    sockfd = socket(af_inet, sock_stream, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = af_inet;
    servaddr.sin_port = htons(serv_port);
    inet_pton(af_inet, argv[1], &servaddr.sin_addr);
    connect(sockfd, (sa *) &servaddr, sizeof(servaddr));
    str_cli(stdin, sockfd);   
    exit(0);
}
Void str_cli(file *fp, int sockfd)
{
    int            maxfdp1;
    fd_set        rset;
    char        sendline[maxline], recvline[maxline];
    fd_zero(&rset);
    for ( ; ; ) {
        fd_set(fileno(fp), &rset);
        fd_set(sockfd, &rset);
        maxfdp1 = max(fileno(fp), sockfd);
        select(maxfdp1, &rset, null, null, null);
        if (fd_isset(sockfd, &rset)) {   
            if (readline(sockfd, recvline, maxline) == 0)
                err_quit("str_cli: server terminated prematurely");
            fputs(recvline, stdout);
        }
        if (fd_isset(fileno(fp), &rset)) { 
            if (fgets(sendline, maxline, fp) == null)
                return;       
            writen(sockfd, sendline, strlen(sendline));
        }
    }
}
1、请指出程序编码不当的地方。
2、该代码是否能完整实现功能,如果不能,什么情况下会出现问题?

这题完全是《unix网络编程》中的例子,书上有详解

1. 不当的地方可能是主函数中socket函数未作错误处理

2.  if (fgets(sendline, maxline, fp) == null)
         return;  

这里在批量输入时有问题,fgets判断返回stdio缓冲区的第一行,其余留在缓冲区中,然后就writen(sockfd, sendline, strlen(sendline);然后继续select,不管stdio缓冲区中还有待发送的数据。

另外,如果读到EOF,就return到主函数,然后退出了,但是可能还有数据在网络上,造成数据没有接收完全。

正确的方式,应该是:

void str_cli(file *fp, int sockfd)
{
 int maxfdp1, stdineof, n;
 fd_set rset;
 char buf[maxline];
 stdineof = 0;
 fd_zero(&rset);

 for ( ; ; ) {
  if( stdineof == 0) {
   fd_set(fileno(fp), &rset);
  }
  fd_set(sockfd, &rset);
  maxfdp1 = max(fileno(fp), sockfd);
  select(maxfdp1, &rset, null, null, null);

  if (fd_isset(sockfd, &rset)) {   
   if((n = Read(sockfd, recvline, maxline)) == 0) {
    if(stdineof == 1)
     return;
    else
     err_quit("str_cli: server terminated prematurely");
   write(fileno(stdout), buf, n);
  }

  if (fd_isset(fileno(fp), &rset)) { 
   if( (n=read(fileno(fp), buf, maxline)) == 0) {
    stdineof = 1;
    shutdown(sockfd, SHUT_WR);
    FD_CLR(fileno(fp), &ret);
    continue;
   }
   writen(sockfd, buf, n);
  }
 }
}

《unix网络编程》我是陆陆续续看的,始终没看完,觉得在linux上开发网络程序终是麻烦,《windows网络编程技术》倒是本好书,还是微软封装的那些IO模型好用些

原创粉丝点击