端口套接字最大可发送的数据量

3
我已经实现了一个程序,它从客户端获取输入,在服务器上执行操作并将数据写入客户端。我选择了ls命令作为示例。
现在我的疑惑是:
1)如果输入的字节数非常大怎么办?
2)通过套接字端口可以发送的最大数据量是多少? client.c
int main()
{
        FILE *fp;
        int servfd, clifd;
        struct sockaddr_in servaddr;
        struct sockaddr_in cliaddr;
        int cliaddr_len;
        char str[4096], clientip[16];
        int n;

        servfd = socket(AF_INET, SOCK_STREAM, 0);
        if(servfd < 0)
        {
                perror("socket");
                exit(5);
        }

        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(SERVPORT);
        servaddr.sin_addr.s_addr = inet_addr(SERVIP);

        if(bind(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
        {
                perror("bind");
                exit(0);
        }

        listen(servfd, 5);

        printf("Server is waiting for client connection.....\n");

        while(1)
        {
                cliaddr_len=sizeof(cliaddr);
                clifd = accept(servfd, (struct sockaddr *)&cliaddr, &cliaddr_len);

                strcpy(clientip, inet_ntoa(cliaddr.sin_addr));
                printf("Client connected: %s\n", clientip);

                if(fork() == 0)
                {
                        close(servfd);
                        while(1)
                        {
                                n = read(clifd, str, sizeof(str));
                                str[n] = 0;

                                if(strcmp(str, "end") == 0)
                                {
                                        printf("\nclient(%s) is ending session and server is waiting for new connections\n\n", clientip);
                                        break;
                                }
                                else if (strcmp(str, "ls") == 0) {
                                        system("ls >> temp.txt");
                                        fp = fopen("temp.txt", "r");
                                        fread(str, 1, 500, fp);
                                        remove("temp.txt");
                                        }
                                else
                                        printf("Received from client(%s): %s\n", clientip, str);

                                write(clifd, str, strlen(str));
                        }
                        close(clifd);
                        exit(0);
                }
                else
                {
                        close(clifd);
                }
        }
}

server.c

int main()
{
        int sockfd;
        struct sockaddr_in servaddr;
        char str[500];
        int n;

        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(SERVPORT);
        servaddr.sin_addr.s_addr = inet_addr(SERVIP);

        if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
        {
                printf("Could not connect to server: %s\n", strerror(errno));
                exit(1);
        }

        while(1)
        {
                printf("Enter message: ");
                scanf(" %[^\n]", str);
                write(sockfd, str, strlen(str));

                if(strcmp(str, "end") == 0)
                        break;

                n  = read(sockfd, str, sizeof(str));
                str[n] = 0;
                printf("Read from server: %s\n", str);
        }

        close(sockfd);
}

2
我认为每个使用套接字编程的人都必须阅读Beej's Guide to Network Programming - Anish Ramaswamy
2个回答

3
对于你的第一个问题,大量数据会被分成许多数据包,并逐个发送。这是操作系统内部完成的。一个数据包的大小取决于你的系统操作系统(你可以改变它,这称为MTU最大传输单元)。
对于你的第二个问题,通过套接字端口发送的数据可能是无限的,因为只要你想发送数据,它就会发送。没有限制!

最近我一直在使用套接字发送许多大文件,但是我发现它会在大约7GB后自动断开连接,原因不明。我不知道为什么,但我认为有一个限制。此外,在另一台设备上,它在20GB后自动断开连接,所以我认为这取决于设备。然而,每当它断开连接时,我都会告诉它重新连接。通过这种方式,我可以尽可能地发送数据。 - Mudit Bhatia

3

问:如果输入的字节数非常大怎么办?通过套接字端口可以发送的最大数据量是多少?

答:TCP/IP流的大小没有限制。理论上,您可以发送和接收无限数量的字节。

... 但是...

1)接收者绝不能假设会一次性读取所有字节。您必须始终在循环中读取套接字数据,每次读取尽可能多的数据,并将其附加到已经读取的数据中。

2)您可以一次发送“大量”数据,但操作系统将在后台缓冲它。

3)即使如此,还存在操作系统限制。例如,在此处,最大发送缓冲区大小为1,048,576字节:

http://publib.boulder.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_send.html

如果需要发送更多,则必须在循环中使用send()。

PS:

如Anish所建议的那样,请务必查看Beej的网络编程指南:

http://beej.us/guide/bgnet/output/html/multipage/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接