2015-06-18 5 views
0

Я хочу отправить файл с клиента на сервер через сокет. да, он отправляет файл, но полученный файл на сервере не является полным или полным, как исходный.C++ - Файл не заполнен Полный

Так что тестовый файл изначально имеет «это тест» в нем, и полученный файл имеет «это»
да это только 4 буквы
я пытался изменить оригинал один становится «MyMomGoesToTheMarket» и получил файл имеет «MyMo». еще 4 буквы, которых я не ожидаю.

Кто-нибудь знает, как решить эту проблему и решение?

Вот клиент:

#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; 
} 

и вот код сервера:

#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; 
} 
+1

'sizeof (rbuffer)' в вашем вызове 'int k = recv (ClientAcc, rbuffer, sizeof (rbuffer), NULL);' задает размер указателя на вашей архитектуре (скорее всего, 4 или 8, и на основе на вашу проблему его 4). Что вам нужно, это 'strlen (rbuffer)' -1 или 'Size'-1 (1 для нулевого терминатора) – Alejandro

+0

@Alejandro, вы должны преобразовать свой комментарий в ответ. –

+0

Спасибо @RSahu, я просто сделал =) – Alejandro

ответ

1

В recv функции вашего сервера кодов, вы будете переходящая в sizeof(rbuffer) - количество байтов для чтения из сокета. Однако rbuffer является указателем, и, таким образом, принимая размер, он вернет размер указателя на вашу архитектуру, который обычно составляет 4 или 8 байт, а так как ваш код сервера считывает только 4 байта, sizeof(rbuffer) вернет 4 в вашу систему.

Чтобы решить эту проблему, вам нужно пройти в любом Size -1 или strlen(rbuffer) -1 в вызове

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

Так это будет выглядеть следующим образом:

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

Это на самом деле читать до Size -1 байта из сокета. Затем вам нужно будет добавить нулевой терминатор в конец rbuffer.

rbuffer[k] = '\0'; 

Кроме того, вы должны сделать то же самое изменение в этой строке:

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

который имеет такую ​​же проблему, как и раньше - он пишет только (в данном случае 4) байты из rbuffer.

+0

он все еще не работает. i change int k = recv (ClientAcc, rbuffer, sizeof (rbuffer), NULL); - int k = recv (ClientAcc, rbuffer, размер, NULL); но все еще не работает – codeJr

+0

Не могли бы вы проверить значение 'Size'? – Alejandro

+0

Извините, я имею ввиду, что я перехожу к int k = recv (ClientAcc, rbuffer, Size-1, NULL) , и проблема все та же. – codeJr

Смежные вопросы