1

I am very new to socket programming, and i am trying to send over TCP connection but getting few errors.

here is my code

        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);

` So this to find the size of my file. most of the code i am trying it out from other questions in here but it didnt solve my problem. ' my send and recv:

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");

on the client side:

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);

So, i know it is not very efficient and i am not sure if there are similar questions as i have been digging in here for a few weeks now.

-is there a better way i can make a char*[]? as i dont know the size of the files i want to send yet. - does ftell() and sifeof() work the same way? -when i check for the size i recved from the server it is alays wrong. Ex: server file: 32633513, recv size: 3263 -most of the code i have taken from other problems and combined it. if you see anything that is not needed do tell me so i take notes of that.

2
  • TCP is a streaming protocol; any recv may get just one byte, or all of them, or any amount in between. (It is not he case that one recv receives what was sent in one send.) Commented Apr 16, 2020 at 9:47
  • Also, byteRecv starts off at zero and is then doubled with every successful recv, so it can't be anything other than zero, ever. Commented Apr 16, 2020 at 9:50

1 Answer 1

0

There is a lot of wrong things but that may correct your problem at first:

On the client side replace (your are both decrementing the total count of bytes and the received ones with the wrong value):

Size -= byteRecv;
byteRecv += byteRecv;

with:

byteRecv += recvCheck; // actualizes the count of received bytes

The other problem is your buffer size. Never try to get an entire file in memory, this is nonsense in general; files are usually managed chunks by chunks. As you are reading at most 1025 bytes in each loop, then only use a buffer of size 1025, you don't need more. Same for reading and writing...

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you that solved the Main problem actually. But now aside of having the Size of the file transfered wrongly, is there a better way for me to check the recved data? For example: if the file size is 3000 and i have recved 3050, then whats gonna happen? for my program i recved 6k of bytes althou the actual value of the sized recvied is less than 4k of bytes.
and for the buffer, i can juse use a buffer of size 1025 instead? and it shall do the same writing for the whole file?
If you send 3000 bytes, you can't read 3050... Usually the file length is sent at the beginning so that the client will know it.
More generally, you should know that tehre is NO guaranty that bytes are read the same way they are sent, that means that is you need, say N bytes, you'll have to read them in a loop (network delivers the bytes in chunks).
i see alright. so after i send the file size, my buffer shouldnt be as big as the file size but as big enough to accept the chunks sent ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.