c - 无法通过 TCP 连接发送整个文件! (UNIX C)

标签 c sockets unix

所以我编写了一个多线程网络服务器,这是该程序的一个函数。该函数采用输出文件描述符 (fd)、内容类型、指向要提供的数据的指针 (*buf) 和数据大小 (numbytes) >)。它总是卡在 5775 字节!我尝试使用 write() 而不是 send(),但无济于事!我尝试一次发送整个 buf,甚至尝试将其分块传输,但是 wget 显示它停留在 5775 字节!这是代码:

int return_result(int fd, char *content_type, char *buf, int numbytes)
{
    char out_buf[BUF_SIZE], numb[6];
    int buf_len, total = 0, buf_size;
    long int i = 0;
    sprintf(numb, "%d", numbytes);
    strcpy(out_buf, "HTTP/1.1 200 OK \nContent-Type: ");
    strcat(out_buf, content_type);
    strcat(out_buf, "\nContent-Length: ");
    strcat(out_buf, numb);
    strcat(out_buf, "\nConnection: Close\n  \n");
    printf("\nSending HTTP Header\n %d bytes sent!",
           send(fd, out_buf, strlen(out_buf), 0));
    char *start = NULL, *str = NULL, *temp = NULL;
    start = buf;
    printf("\n Start Pointer Val = %ld", &start);
    while (start != NULL) {
        printf("\n While Loop");
        if (i + 2048 * sizeof(char) < numbytes) {
            printf("\n If 1");
            str = (char *)malloc(sizeof(char) * 2048);
            memcpy(str, start, sizeof(char) * 2048);
            i = i + 2048 * sizeof(char);
            buf_size = send(fd, str, 2048, 0);
            free(str);
            printf("\n Sent %d bytes total : %d", buf_size, total =
                   total + buf_size);

            temp = start + sizeof(char) * 2048;
            start = temp;

        } else {

            i = numbytes - i * sizeof(char);
            if (i > 0) {
                printf("\n If 2");
                printf("\n Value of i %d", i);
                str = (char *)malloc(sizeof(char) * i);
                memcpy(str, start, sizeof(char) * i);
                printf("Total bytes finally sent:%d", total =
                       total + send(fd, str, i, 0));
                if (total == numbytes) {
                    printf("\nTransfer Complete!");
                }
                free(str);

            }
            start = NULL;
        }
    }
    printf("out of loop!");
    return 0;
}

最佳答案

我建议将您的代码替换为 Advanced Programming in the Unix Environment, 2nd edition 中的以下 writen() 函数:

ssize_t             /* Write "n" bytes to a descriptor  */
writen(int fd, const void *ptr, size_t n)
{
        size_t          nleft;
        ssize_t         nwritten;

        nleft = n;
        while (nleft > 0) {
                if ((nwritten = write(fd, ptr, nleft)) < 0) {
                        if (nleft == n)
                                return(-1); /* error, return -1 */
                        else
                                break;      /* error, return amount written so far */
                } else if (nwritten == 0) {
                        break;
                }
                nleft -= nwritten;
                ptr   += nwritten;
        }
        return(n - nleft);      /* return >= 0 */
}

此代码已经过调试并且已知可以正常工作,并且进一步允许 write(2) 一次性写入 PIPE_BUF 字节,以便在运行良好时获得更好的速度。

不过,如果

send(2) 应该 阻止它发送您请求的所有数据。我认为更有趣的是使用简单的 send(2) 调试版本,而无需任何周围的努力将事物分成 block 。

write(2)send(2) 更好的是 sendfile(2) -- 打开文件,传递描述符和套接字发送到sendfile(2),并让内核为您处理这一切,如果可能的话使用零复制机制。

最后一点:HTTP uses CRLF ,而不是简单的回车符。每个 \n 应替换为 \r\n

关于c - 无法通过 TCP 连接发送整个文件! (UNIX C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8528638/

相关文章:

在 C 中创建子进程

c - SCSI 通用 write() 线程安全吗?

c - 如何在 C 库中使用 opendir 和 readdir 忽略隐藏文件

git - 如何使用 git add 或 git lfs 跟踪大量文件

java - handshake.getPeerCertificates() 双向握手中的空指针

linux - Linux 中的共享内存 fork 进程学习

c - 如何设置 Visual Studio 以理解 GCC 定义?

c - Arm Gcc 弱别名重新定义

c++ - 具有多个客户端的服务器 : how to forward message from one client to another

node.js - NodeJS - 响应流