C服务器客户端FTP。有时当它是一个大文件时,我不会阅读我发送的所有信息

时间:2017-07-23 20:33:03

标签: c sockets ftp

我正在做一个FTP服务器和客户端。 我使用send函数发送(数据大小为64000 max + sizeof(struct header))的包,其中包含一个struct头,它给出了我需要用recv函数和文件数据读取的数据的大小。 我不明白为什么,当我发送一个大文件时,当我读取包时,有时我不会读取其中一个标题,所以我把文件的数据放在我的头文件结构中,而malloc崩溃显然是因为标头结构是是的,我试图分配太多。

char    *ftp_get_package(int sock, t_header *header)
{
    char    *buff;
    ssize_t ret;

    ret = 0;
    while ((ret += recv(sock, header, sizeof(t_header), 0)) >= 0
            && (size_t)ret < sizeof(t_header))
            ;
    ft_putstr("|"); // DEBUG
    ft_putstr((char*)header); // DEBUG
    ft_putendl("|"); // DEBUG
    ft_putnbr(header->nb_bytes); // DEBUG
    ft_putendl(" <--- get"); // DEBUG
    if (ret != -1)
    {
        if (!(buff = (char*)malloc(header->nb_bytes + 1)))
            ftp_error(NULL, "ERROR: malloc failure\n", 0);
        ret = 0;
        while ((ret += recv(sock, buff + ret, header->nb_bytes, 0)) >= 0
            && (size_t)ret < header->nb_bytes)
            ;
        if (ret > 0)
        {
            buff[ret] = '\0';
            return (buff);
        }
    }
    if (ret == -1)
        ftp_error(NULL, "ERROR: recv failure\n", 0);
    return (NULL);
}

void    ftp_send_package(char *str, int sock, char flag, long size)
{
    t_header    header;
    ssize_t     ret;
    char        *package;
    int         size_header;

    if (size == -1)
        header.nb_bytes = ft_strlen(str);
    else
        header.nb_bytes = size;
    ft_putnbr(header.nb_bytes); // DEBUG
    ft_putendl(" <--- send"); // DEBUG
    header.flag = flag;
    size_header = sizeof(t_header);
    if (!(package = malloc(size_header + header.nb_bytes)))
        ftp_error(NULL, "ERROR: malloc failure !\n", sock);
    ft_memcpy(package, &header, size_header);
    ft_memcpy(package + size_header, str, header.nb_bytes);
    if ((ret = send(sock, package, size_header + header.nb_bytes, 0)) == -1)    
        ftp_error(NULL, "ERROR: send failure\n", sock);
    free(package);
}

kiki是我用来调试的文件。 里面有&#39; *#64; * 64000然后&#39; * 64000然后&#39; * 64000 ...&#39; *&#39; * 64000 kiki大小是1 280 000

Serveur调试

11 <--- get // get -> "mkfile kiki" to create file kiki
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
||
64000 <--- get
|mmmmmmmmmmmmmmmm�A| // putstr of header
7885078839350357357 <--- get
serveur(30378,0x7fff7b25c000) malloc: *** 
mach_vm_map(size=7885078839350358016) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
ERROR: malloc failure

客户端调试

ftp -> put kiki
11 <--- send // send -> "mkfile kiki"
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
64000 <--- send
1 <--- send
0 <--- send
0 <--- send

如果您需要更多详细信息,请向我提问

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您的recv()循环请求的数据多于缓冲区中的空间,因为您没有减去已经从限制中读取的字节数。你需要这样做:

while ((ret += recv(sock, header, sizeof(t_header) - ret, 0)) >= 0
        && ret < sizeof(t_header))
        ;

    while ((ret += recv(sock, buff + ret, header->nb_bytes - ret, 0)) >= 0
        && ret < header->nb_bytes)
        ;

此外,这看起来可能是一个问题:

ft_putstr((char*)header);

您没有显示ft_putstr()struct header定义,但似乎该函数需要以空字符结尾的字符串参数,而header不是字符串。