C++ - 文件未满到达

C++ - File is not Full arrived

本文关键字:文件 C++      更新时间:2023-10-16

我想通过套接字将文件从客户端发送到服务器。 是的,它发送一个文件,但服务器中收到的文件不像原始文件那样完整或完整。

所以测试文件中原本有"这是一个测试",收到的文件有"这个"
是的,只有 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:%dn", ClientIP, ClientPort);

}

void receiving() {

                    //receive the file size 
                    recv(ClientAcc,Filesize,1024,0);
                    Size = atoi((const char*)Filesize);
                    printf("File size : %dn",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;
}

在服务器代码的recv函数中,将sizeof(rbuffer)作为要从套接字读入的字节数传入。 然而,rbuffer是一个指针,因此取一个大小它将返回你的架构上指针的大小,通常是 4 或 8 个字节,并且由于您的服务器代码只读取 4 个字节,sizeof(rbuffer)会在您的系统上返回 4

要解决此问题,您需要将 -1 Sizestrlen(rbuffer) -1 传递到调用

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

所以它看起来像这样:

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

这实际上会从套接字读取多达 Size -1 个字节。然后,您需要将空终止符添加到 rbuffer 的末尾。

rbuffer[k] = '';

此外,您需要在此行中进行相同的更改:

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

它与以前有相同的问题 - 它只从 rbuffer 写入(在本例中为 4)字节。