簡體   English   中英

通過 TCP/IP 發送文件

[英]Sending files via TCP/IP

我正在嘗試使用 Windows 上的 C++ 程序通過 TCP/IP 發送文件。 發送和接收工作正常。 但在收到的文件中,每 40 個字符后出現兩個逗號。 如果我發送例如:

123456789
123456789
123456789
123456789
123456789
123456789
23456789
123456789
123456789
123456789
123456789
123456789
123456789
123456789

收到的文件是:

123456789
123456789
123456789
123456789
123456789
„123456789
123456789
123456789
123456789
123456789
„123456789
123456789
123456789
123456789

這是用於發送文件的服務器代碼:

static int send_client_file(SOCKET sock, char *Sbuffer){

int n = 0;
char* f_name = "send.txt";
//char* f_name = "server.c";

cout << endl << "Waiting for the client message" << endl;
FILE *fp = fopen(f_name, "r");
if (fp == NULL)
{
    cout << "ERROR : File " << f_name << " not found ";
    perror("fopen()");
    exit(errno);
}

//bzero(Sbuffer, 50); // on vide le buffer d'envoie
memset(Sbuffer, 0, 50);
while((n = fread(Sbuffer, sizeof(char), 50, fp)) > 0)
{
    if((n = send(sock, Sbuffer, strlen(Sbuffer), 0)) < 0)
    {
        perror("send()");
        exit(errno);
    }
    memset(Sbuffer, 0, 50);
}

cout << "file sent" << endl;

return n;
}

這是接收它的客戶端代碼:

int static recv_server_file(SOCKET sock, char *buffer){

int n = 0;
int m = 0;

cout << endl << "Receiving file from the server..." << endl;
char* f_name = "receive.txt";
FILE *fp = fopen(f_name, "a");
if (fp == NULL)
{
    cout << "ERROR : File " << f_name << "not found " << endl;
    perror("fopen()");
    exit(errno);
}

else {

while(n = recv(sock, buffer, Rbuffer_size, 0))
{
    if (n < 0)
    {
        perror("recv()");
        exit(errno);
    }
    m = fwrite(buffer, sizeof(char), n, fp);

    if(m < n)
    {
        cout << "File write failed." << endl;
        break;
    }

    break;
    memset(buffer, '/0', Rbuffer_size);
}
cout << "ok!" << endl;

fclose(fp);
}
cout << "The received data is : " << buffer << endl ;

return m;

}

如您所見,接收文件中出現了“,,”。 知道如何解決這個問題嗎?

從表面上看,您似乎有緩沖區溢出。 請注意,不需要的字符出現在 50 個字節之后(而不是您在問題中所說的 40 個字節)。 您的緩沖區長度為 50 個字符。

您不能在讀入的緩沖區上調用 strlen() ,因為 strlen 需要終止空字符才能工作。 也就是說,您需要緩沖區為 51 個字符。

這可能不是唯一的問題,但肯定是其中的一部分。

這里的問題太多了。

這是發送文件的服務器代碼:

static int send_client_file(SOCKET sock, char *Sbuffer){

int n = 0;
char* f_name = "send.txt";
//char* f_name = "server.c";

cout << endl << "Waiting for the client message" << endl;
FILE *fp = fopen(f_name, "r");
if (fp == NULL)
{
    cout << "ERROR : File " << f_name << " not found ";
    perror("fopen()");
    exit(errno);
}

//bzero(Sbuffer, 50); // on vide le buffer d'envoie
memset(Sbuffer, 0, 50);

不必要。 消除。

while((n = fread(Sbuffer, sizeof(char), 50, fp)) > 0)
{
    if((n = send(sock, Sbuffer, strlen(Sbuffer), 0)) < 0)

其中的send()部分應該是send(sock, Sbuffer, n, 0) 這是根本問題。 您發送的長度錯誤。 您還假設剛剛讀取的數據實際上包含一個空值,對此無法保證。 strlen()調用可能會溢出緩沖區並導致未定義的行為。

    {
        perror("send()");
        exit(errno);
    }
    memset(Sbuffer, 0, 50);

memset()是不必要的。 消除。

}

cout << "file sent" << endl;

return n;
}

在這里你返回零。 我看不出重點。

這是接收它的客戶端代碼:

int static recv_server_file(SOCKET sock, char *buffer){

int n = 0;
int m = 0;

cout << endl << "Receiving file from the server..." << endl;
char* f_name = "receive.txt";
FILE *fp = fopen(f_name, "a");
if (fp == NULL)
{
    cout << "ERROR : File " << f_name << "not found " << endl;
    perror("fopen()");
    exit(errno);
}

else {

while(n = recv(sock, buffer, Rbuffer_size, 0))
{
    if (n < 0)
    {
        perror("recv()");
        exit(errno);
    }
    m = fwrite(buffer, sizeof(char), n, fp);

    if(m < n)
    {
        cout << "File write failed." << endl;
        break;
    }

    break;
    memset(buffer, '/0', Rbuffer_size);

再次memset()是不必要的:刪除。

}

在您的客戶端代碼中,緩沖區實際上從未被設置過。 那可能是問題所在。

第一次迭代假設 'buffer' 已經設置為 '\\0' 並且這個代碼是多余的if (n < 0) { perror("recv()"); exit(errno); } if (n < 0) { perror("recv()"); exit(errno); } if (n < 0) { perror("recv()"); exit(errno); }由於同時(......)已經將檢查和你打破循環了你memset的前迭代結束,並通過這樣做,使整個循環冗余。 請執行 memset 以排除那些可能的罪魁禍首,您也可以應用這些建議,但這取決於您。

編輯:並且通過使循環冗余,您可能不會收到所有數據。

編輯#2:您也忽略了“發送”的返回值。 從 msdn 頁面:

如果沒有發生錯誤,send 返回發送的總字節數,可以小於 len 參數中請求發送的字節數。 否則返回 SOCKET_ERROR 值,調用 WSAGetLastError 可以檢索到具體的錯誤代碼。

因此,數據可能會被丟棄,因為無法保證它會立即發送所有數據。

編輯#3(對不起,很多編輯)你也沒有在服務器代碼中關閉你的文件句柄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM