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

因此,测试文件中最初包含“ this is a test”,而接收到的文件中包含“ this”
是的,只有四个字母
我试图将原来的变成“ 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;
}

最佳答案

在服务器代码的recv函数中,您要传入sizeof(rbuffer)作为要从套接字读取的字节数。但是rbuffer是一个指针,因此采用sizeof它将返回架构上的指针大小,通常为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));


与以前有同样的问题-它仅从rbuffer写入(在这种情况下为4)字节。

10-04 21:56
查看更多