codeJr
codeJr

Reputation: 11

C++ - File is not Full arrived

i want to send a file from client to server through socket . yes it sends a file but the received file in the server is not full or complete like the original one.

So the test file originally has "this is a test" in it, and the received file has "this"
yes it's only 4 letters
i tried to change the original one becomes "MyMomGoesToTheMarket" and received file has "MyMo" . still 4 letters which is not what i expect.

anyone know how to solve this problem and the solution ?

Here is the client :

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <fstream>

using namespace std;



SOCKET clientsock;
WSADATA winsock;
sockaddr_in serverAddr , addr;
int Addrlen = sizeof(serverAddr);
FILE *File;
unsigned long Size;


void startClient() {


    WSAStartup(MAKEWORD(2,2), &winsock);

    if(LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ){

        WSACleanup();

    }


    clientsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(6091);

    connect(clientsock,(sockaddr*)&addr,sizeof(addr));

    printf("socket connected... \n");


}


void sending() {

                //preparing the file 
          ifstream myfile;
          myfile.open("B:\RelativeLayout.txt",ios::in | ios::binary | ios::ate);

          if(myfile.is_open()) {

              printf("File open OK ! \n ");


          }else {

              printf("File not open ! \n ", WSAGetLastError());

          }

          //preparing the file size

          long Size  ;
          myfile.seekg(0,fstream::end);
          Size = myfile.tellg();
          myfile.close();

          printf("File Size  : %d bytes.\n ",Size);

          char cisi[10];
          sprintf(cisi, "%i",Size);
          send(clientsock,cisi,10,0); // file size sent         

          //sending the file 

          char *rbuffer;

          myfile.open("B:\RelativeLayout.txt",ios::in | ios::binary | ios::ate);

          if(myfile.is_open()) {

              myfile.seekg(0, ios::beg);

              rbuffer =  new char[Size];
              myfile.read(rbuffer, Size);

              //send(clientsock, rbuffer, Size, 0);

              int j = send(clientsock, rbuffer, Size, NULL); //send to server
             if (j == -1){
                           cout << "Error sending file to server :(" << endl;
                         }else {
                                        cout << " sending file to server succeed" << endl;
                               } 



              myfile.close();

          }


}





int _tmain(int argc, _TCHAR* argv[])
{

    startClient();
    sending();

    system("PAUSE");
    return 0;
}

and here is the server code :

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <fstream>

using namespace std;

SOCKET servsocket, ClientAcc;
WSAData winsock;
sockaddr_in addr,incomingAddress;
int addrlen = sizeof(sockaddr_in);
int addresslen = sizeof(incomingAddress);
char *Filesize = new char[1024];
long  Size; 




void start() {

            //socket initialization
    WSAStartup(MAKEWORD(2,2), &winsock);

    //socket check

    if(LOBYTE(winsock.wVersion) !=2 || HIBYTE(winsock.wVersion) != 2 ) {

        WSACleanup();
    }


    servsocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6091);
    bind(servsocket, (sockaddr*)&addr, sizeof(addr));

    listen(servsocket, 5);

    ClientAcc = accept(servsocket, (sockaddr*)&incomingAddress, &addresslen);

    char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
    int  ClientPort = ntohs(incomingAddress.sin_port);
    printf("Client Connected ... \n");
    printf("IP : %s:%d\n", ClientIP, ClientPort);


}


void receiving() {



                    //receive the file size 

                    recv(ClientAcc,Filesize,1024,0);
                    Size = atoi((const char*)Filesize);
                    printf("File size : %d\n",Size);

                    //receive the file

                    char *rbuffer;
                    rbuffer = new char[Size];
                    int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);
                    if (k < 0){
                                cout << "Error uploading file" << endl;
                              }else {


                                            fstream file;
                                            file.open("B:\FileReceived.txt", ios::out|ios::binary| ios::ate);
                                            file.write(rbuffer, sizeof(rbuffer));                             
                                            file.close();
                                            cout << "File received!" << endl;



                                    }






}


int _tmain(int argc, _TCHAR* argv[])
{

    start();
    receiving();
    system("PAUSE");
    return 0;
}

Upvotes: 0

Views: 64

Answers (1)

Alejandro
Alejandro

Reputation: 3082

In your server code's recv function, you're passing in sizeof(rbuffer) as the amount of bytes to read in from the socket. rbuffer is a pointer however, and thus taking a sizeof it will return the size of a pointer on your architecture , which is typically 4 or 8 bytes, and since your server code is only reading 4 bytes, sizeof(rbuffer) would return 4 on your system.

To solve this, you need to pass in either Size-1 or strlen(rbuffer)-1 into the call to

int k = recv(ClientAcc, rbuffer, sizeof(rbuffer), NULL);

So it would look like this:

int k = recv(ClientAcc, rbuffer, Size-1, NULL);

This would actually read up to Size-1 bytes from the socket. You would then need to add the null terminator to the end of rbuffer.

rbuffer[k] = '\0';

Additionally, you need to make the same change in this line:

file.write(rbuffer, sizeof(rbuffer));

Which has the same problem as before - it only writes (in this case 4) bytes from rbuffer.

Upvotes: 1

Related Questions