鍍金池/ 問答/C  網(wǎng)絡(luò)安全/ 寫了一個(gè) ftp client,但用 socket 接收 LIST 命令的數(shù)據(jù)不

寫了一個(gè) ftp client,但用 socket 接收 LIST 命令的數(shù)據(jù)不完整

接收數(shù)據(jù)在子進(jìn)程中:

char data_buffer[BUFFER_SIZE];
char *ptr = "";
int data_len = 0;
int pre_len = 0;
for (;;)
{
    bzero(data_buffer, BUFFER_SIZE);
    int length = recv(client_data_socket, data_buffer, BUFFER_SIZE, 0);
    if (length == 0)
    {
        close(client_data_socket);
        break;
    }
    else if (length < 0)
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
        {
            continue;
        }
        close(client_data_socket);
        printf("get data failed\n");
        exit(1);
    }
    pre_len = data_len;
    data_len += length;
    char *tmp_ptr = (char *)calloc(data_len, sizeof(char));
    memcpy(tmp_ptr, ptr, pre_len);
    memcpy(tmp_ptr + pre_len, data_buffer, length);
    if (pre_len > 0) free(ptr);
    ptr = tmp_ptr;
}
char *tmp_ptr = (char *)calloc(data_len + 1, sizeof(char));
g2u(ptr, data_len, tmp_ptr, data_len + 1);
printf("%s\n", tmp_ptr);
free(ptr);
free(tmp_ptr);
exit(0);

g2u 方法是編碼轉(zhuǎn)換,把 gbk to utf-8 然后發(fā)現(xiàn)讀出來的數(shù)據(jù)少了一部分,我是在 recv 返回 0 的時(shí)候,判斷數(shù)據(jù)全部接收,可是發(fā)現(xiàn)結(jié)果有問題

顯然,迅雷下載這幾個(gè)字,沒接收完(不知道哪里出了問題) 真正的文件列表

回答
編輯回答
維她命

測試

打印了一下接收到的字節(jié)

..... 32 32 -47 -72 -64 -41 -49 -62 -44 -40 13 10 

32 是空格,13 是\r 10 是\n
-47 -72 -64 -41 -49 -62 -44 -40 這一段我用 vc 打印了一下,正好是迅雷下載

結(jié)論

看來是 g2u 函數(shù)的問題


然后我再看了看,把把outbuf放大(改成了2倍,outlen的值也要改),就可以正確輸出了

看來是多字節(jié)對應(yīng)漢字的問題

GBK編碼,一個(gè)漢字占兩個(gè)字節(jié) UTF-8編碼是變長編碼,通常漢字占三個(gè)字節(jié),擴(kuò)展B區(qū)以后的漢字占四個(gè)字節(jié)。
2017年6月8日 14:22