使用SFML TCP套接字和数据包破坏文件

File Comes Corrupted Using SFML TCP Sockets and packtes

本文关键字:文件 数据包 SFML TCP 套接字 使用      更新时间:2023-10-16

我正在为编写代码,以便客户端连接到服务器,服务器响应并发送.exe文件。我正在使用SFML网络库来编写代码。我可以成功地发送大小正确但md5sum错误的文件,这意味着有些东西正在更改,但我不知道在哪里。这是我的代码,有人能发现我的错误吗。服务器:

#include <SFML/Network.hpp>
#include  <string>
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
    std::string i{ "Hello World" };
    sf::Packet packet;
    //packet << i;
    sf::TcpListener tcpl;
    sf::TcpSocket tcps;
    std::vector<std::string> Buffer;
    std::string tmp;
    std::ifstream fis("C:\Users\Cyber Security\Documents\Repos.git\Agent\x64\Debug\Project1.exe", std::ios::in |    std::ios::binary);

    tcpl.listen(5050);
    std::cout << "Listening" << std::endl;
        tcpl.accept(tcps);
    while (std::getline(fis,tmp))
    {
        Buffer.push_back(tmp);
    };
    packet << static_cast<sf::Uint32>(Buffer.size());
    for (std::vector<std::string>::const_iterator it = Buffer.begin(); it != Buffer.end(); ++it)
        packet << *it;
    sf::Socket::Status status = tcps.send(packet);
    if (status == sf::Socket::Error)
        std::cout << "Error";
    fis.close();
    std::cout << "Packet Sent" << std::endl;
    tcpl.close();
    std::cout << "Socket Closed" << std::endl;
    system("pause");
    return 0;
}

客户:

#include  <SFML/Network.hpp>
#include <string>
#include <fstream>
#include <vector>
#include <iostream>
int main()
{
    std::string h{ "" };
    sf::Packet packet;
    sf::TcpSocket tcps;
    sf::Uint32 size = 0;
    std::vector<std::string> Buffer;
    sf::TcpSocket::Status status= tcps.connect("10.10.10.10", 5050);
    std::ofstream fis;
    if (status == sf::TcpSocket::Status::Done)
    {
        fis.open("Project1.exe", std::ofstream::binary);
        std::cout << "Starting Donwload of Packet" << std::endl;
        status== tcps.receive(packet);
        if (status == sf::Socket::Error)
            std::cout << "Error";
        std::cout << "Packet Received" << std::endl;
    }


        packet >> size;
        for (sf::Uint32 i = 0; i < size; ++i)
        {
            std::string item;
            packet >> item;
            Buffer.push_back(item);
        }
     for (std::vector<std::string>::const_iterator it = Buffer.begin(); it != Buffer.end(); ++it)
        fis << *it;
    fis.close();

    system("pause");
    return 0;
}

您的文件是一个二进制文件。这不是一串字符串。这样读取它已经丢失了字节,即使不通过网络发送它也是如此。将文件视为字节序列:

#include <SFML/Network.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
    sf::Packet packet;
    sf::TcpListener tcpl;
    sf::TcpSocket tcps;
    std::ifstream fis("C:\Users\Cyber Security\Documents\Repos.git\Agent\x64\Debug\Project1.exe", std::ios::binary);
    std::vector<char> fileContents((std::istreambuf_iterator<char>(fis)), std::istreambuf_iterator<char>());
    fis.close();
    tcpl.listen(5050);
    std::cout << "Listening" << std::endl;
    tcpl.accept(tcps);
    packet << static_cast<sf::Uint32>(fileContents.size());
    for (std::vector<char>::const_iterator it = fileContents.begin(); it != fileContents.end(); ++it) packet << *it;
    sf::Socket::Status status = tcps.send(packet);
    if (status == sf::Socket::Error)
        std::cout << "Error";
    std::cout << "Packet Sent" << std::endl;
    tcpl.close();
    std::cout << "Socket Closed" << std::endl;
    system("pause");
    return 0;
}

客户:

#include  <SFML/Network.hpp>
#include <string>
#include <fstream>
#include <vector>
#include <iostream>
int main()
{
    sf::Packet packet;
    sf::TcpSocket tcps;
    sf::Uint32 size = 0;
    sf::TcpSocket::Status status = tcps.connect("10.10.10.10", 5050);
    if (status == sf::TcpSocket::Status::Done)
    {
        std::cout << "Starting Download of Packet" << std::endl;
        status == tcps.receive(packet);
        if (status == sf::Socket::Error)
            std::cout << "Error";
        std::cout << "Packet Received" << std::endl;
    }
    std::ofstream fos("Project1.exe", std::ofstream::binary);
    packet >> size;
    for (sf::Uint32 i = 0; i < size; ++i)
    {
        char item;
        packet >> item;
        fos << item;
    }
    fos.close();
    system("pause");
    return 0;
}

客户端仍然缺少很多错误处理,但无论如何都是POC代码。