C++ 使用C+通过TCP发送文件+;,接收错误的大小

C++ 使用C+通过TCP发送文件+;,接收错误的大小,c++,file,websocket,tcp,transfer,C++,File,Websocket,Tcp,Transfer,我对套接字编程非常陌生,我尝试通过TCP连接发送数据,但很少出错 这是我的密码 FILE* File; char* Buffer; unsigned long Size; File = fopen("C:\\test.zip", "rb"); if (!File) { printf("Error while readaing the file\n");

我对套接字编程非常陌生,我尝试通过TCP连接发送数据,但很少出错

这是我的密码

        FILE* File;
        char* Buffer;
        unsigned long Size;

        File = fopen("C:\\test.zip", "rb");
        if (!File)
        {
            printf("Error while readaing the file\n");
            return;
        }
        // file size 1
        fseek(File, 0, SEEK_END);
        Size = ftell(File);
        fseek(File, 0, SEEK_SET);


        Buffer = new char[Size]; 

        fread(Buffer, Size, 1, File);
        char cSize[MAX_PATH];
        sprintf(cSize, "%i", Size);

        cout << "MAX PATH " << MAX_PATH<<endl;
        cout << "cSize: " << cSize << endl;
        fclose(File);
文件*FILE;
字符*缓冲区;
无符号长尺寸;
File=fopen(“C:\\test.zip”、“rb”);
如果(!文件)
{
printf(“读取文件时出错\n”);
返回;
}
//文件大小1
fseek(文件,0,SEEK_END);
大小=ftell(文件);
fseek(文件,0,搜索集);
缓冲区=新字符[大小];
fread(缓冲区,大小,1,文件);
char cSize[最大路径];
sprintf(cSize,“%i”,大小);

cout有很多错误的事情,但这可能会在一开始纠正您的问题:

在客户端替换(您正在减少字节总数,并且接收到的字节数的值错误):

与:


另一个问题是缓冲区大小。永远不要试图在内存中获取整个文件,这通常是胡说八道;文件通常是逐块管理的。由于每个循环最多读取1025个字节,因此只使用大小为1025的缓冲区,不需要更多。阅读和写作也是一样…

有很多错误的事情,但这可能会在一开始纠正你的问题:

在客户端替换(您正在减少字节总数,并且接收到的字节数的值错误):

与:


另一个问题是缓冲区大小。永远不要试图在内存中获取整个文件,这通常是胡说八道;文件通常是逐块管理的。由于每个循环最多读取1025个字节,因此只使用大小为1025的缓冲区,不需要更多。读写也一样…

TCP是一种流协议;任何
recv
可能只获得一个字节,或全部字节,或两者之间的任何数量。(并非一个
recv
接收一个
send
中发送的内容)而且,
byteRecv
从零开始,然后随着每个成功的
recv
而加倍,所以它不能是零以外的任何东西,永远。TCP是一种流协议;任何
recv
可能只获得一个字节,或全部字节,或两者之间的任何数量。(不是一个
recv
接收一个
send
发送的内容)而且,
byteRecv
从零开始,然后随着每次成功的
recv
而加倍,所以它永远不会是零以外的任何东西。谢谢你,实际上解决了主要问题。但是现在除了错误地传输文件大小之外,还有更好的方法让我检查记录的数据吗?例如:如果文件大小是3000,而我收到了3050,那么会发生什么?对于我的程序,我记录了6k字节,但记录的大小的实际值小于4k字节。对于缓冲区,我可以使用大小为1025的缓冲区?它应该对整个文件执行相同的写入操作?如果发送3000字节,则无法读取3050。。。通常在开始时发送文件长度,以便客户端知道。更一般地说,您应该知道tehre不能保证字节的读取方式与发送方式相同,这意味着您需要,比如说N个字节,您必须在循环中读取它们(网络以块的形式交付字节)。我明白了。所以,在我发送文件大小后,我的缓冲区不应该像文件大小那样大,而应该大到足以接受发送的数据块?谢谢你,这实际上解决了主要问题。但是现在除了错误地传输文件大小之外,还有更好的方法让我检查记录的数据吗?例如:如果文件大小是3000,而我收到了3050,那么会发生什么?对于我的程序,我记录了6k字节,但记录的大小的实际值小于4k字节。对于缓冲区,我可以使用大小为1025的缓冲区?它应该对整个文件执行相同的写入操作?如果发送3000字节,则无法读取3050。。。通常在开始时发送文件长度,以便客户端知道。更一般地说,您应该知道tehre不能保证字节的读取方式与发送方式相同,这意味着您需要,比如说N个字节,您必须在循环中读取它们(网络以块的形式交付字节)。我明白了。所以在我发送文件大小后,我的缓冲区不应该和文件大小一样大,而是应该足够大以接受发送的块?
unsigned long filechunk = 1025;

unsigned long byteSent = 0;
unsigned long bytesToSend = 0;

send(Sub, cSize, MAX_PATH, 0); // File size to client

while (byteSent < Size) {

    if ((Size - byteSent) >= filechunk) {
        bytesToSend = filechunk;
    }
    else {
        bytesToSend = Size - byteSent;
    }
    if (send(Sub, Buffer + byteSent, bytesToSend, 0)) {
        std::cout << "Sent: ";
    }
    byteSent += bytesToSend;
    std::cout << "Size : "<<Size<<"    BytesSent : "<<byteSent<<"   Bytes to send: " << bytesToSend << std::endl;
    system("pause");
int Size;
char* Filesize = new char[5000000]; // is there a better way? my sfiles size are unknown but at least 50mb

if (recv(Socket, Filesize, 5000000, 0)) // File size
{
    Size = atoi((const char*)Filesize);
    printf("File size: %d\n", Size);
}

char* Buffer = new char[Size];
FILE* File;
File = fopen("test.zip", "wb"); //start copying from the server, creating the file first.
std::string convert;
long conv;

std::cout << "Size: " << Size << std::endl;

int total=Size;
int byteRecv = 0;
int recvCheck;
int bytes = 1025;

//getting the file
while (byteRecv < Size ) {

    recvCheck = recv(Socket, Buffer, bytes, 0);
    if (recvCheck >0) // File
    {
        fwrite(Buffer, 1, byteRecv, File);

        std::cout << "Recieved:" << byteRecv << std::endl;

        Size -= byteRecv;
        byteRecv += byteRecv;
        std::cout << "Error: " << WSAGetLastError();
    }
    else {
        std::cout << "Error: " << WSAGetLastError();
        total += 1; // the loop often get into infinit loop so i force it in case of this error.
        if (total > 3) {
            break;
        }
    }
}
fclose(File);
Size -= byteRecv;
byteRecv += byteRecv;
byteRecv += recvCheck; // actualizes the count of received bytes