0

我有两个服务器代码:

  1. 第一个服务器:每次向客户端发送一个字符,直到字符串完成

    int
    main(int argc, char **argv)
    {
        int                 listenfd, connfd;
        struct sockaddr_in  servaddr;
        char                buff[MAXLINE];
        time_t              ticks;
            char                            temp[1];
            int                             i = 0;
    
        listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port        = htons(9999); /* daytime server */
    
        Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    
        Listen(listenfd, LISTENQ);
    
        for ( ; ; ) {
            connfd = Accept(listenfd, (SA *) NULL, NULL);
    
            ticks = time(NULL);
            snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
    
            for(i = 0; i < strlen(buff); i++)
            {
                temp[0] = buff[i];
                Write(connfd, temp, strlen(temp));
            }
    
            Close(connfd);
        }
    }
    
  2. 第二台服务器:向客户端发送一个字符串

    int
    main(int argc, char **argv)
    {
        int                 listenfd, connfd;
        struct sockaddr_in  servaddr;
        char                buff[MAXLINE];
        time_t              ticks;
            char                            temp[1];
            int                             i = 0;
    
        listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port        = htons(9999); /* daytime server */
    
        Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    
        Listen(listenfd, LISTENQ);
    
        for ( ; ; ) {
            connfd = Accept(listenfd, (SA *) NULL, NULL);
    
            ticks = time(NULL);
            snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
    
            Write(connfd, buff, strlen(buff));
            Close(connfd);
        }
    }
    
  3. 客户端:接收服务器发送的字符

    int
    main(int argc, char **argv)
    {
        int                 sockfd, n;
        char                recvline[MAXLINE + 1];
        struct sockaddr_in  servaddr;
            int count = 0;
    
        if (argc != 2)
            err_quit("usage: a.out <IPaddress>");
    
        if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
            err_sys("socket error");
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port   = htons(9999);  /* daytime server */
        if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
            err_quit("inet_pton error for %s", argv[1]);
    
        if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
            err_sys("connect error");
    
        while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
            recvline[n] = 0;    /* null terminate */
                    count++;
            if (fputs(recvline, stdout) == EOF)
                err_sys("fputs error");
        }
        if (n < 0)
            err_sys("read error");
            printf("read time:%d\n", count);
    
        exit(0);
    }
    

结果是变量计数的输出都是1。我的问题是为什么第一台服务器的输出是1,我认为第一台服务器的结果应该是strlen(buff)?

PS:我在同一台机器上运行服务器和客户端。

4

1 回答 1

2

TCP 是一种流协议。因此,一侧的写入次数不会导致另一侧的读取次数相同,因为协议不保留有关如何写入套接字的信息。

通常,在发送方,在发送数据包之前会有延迟,以防您将更多数据写入套接字,以便将更多数据填充到同一个数据包中。其原因之一是编写不当的服务器可能会用单字节数据包淹没网络。

在接收方,协议不知道为什么您的数据可能作为单独的数据包到达,它可能因为 MTU 而被拆分,它可能在途中被某些数据包检查软件或设备重新组装,所以无论何时你从你的套接字读取它会给你尽可能多的数据,不管它是如何发送给你的。

在像您的设置这样的本地机器上,客户端可能在服务器写入时甚至没有运行,因此即使在发送方没有缓冲,它也不会开始读取,直到服务器写入所有内容,因此它将读取所有内容一口气。或者不是,你可能不走运,你的服务器被抢占了足够长的时间,以至于你内核中的 TCP 实现认为你不会再发送任何数据,向客户端发送一个字节,客户端被调度在服务器再次运行之前运行,客户端在第一次读取时只会收到一个字节。

于 2013-09-24T14:51:28.357 回答