c++ - 使用 SFML TCP 套接字和数据包损坏文件

标签 c++ sockets tcp sfml packets

我正在编写代码,让客户端连接到服务器,然后服务器响应并发送 .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 代码。

关于c++ - 使用 SFML TCP 套接字和数据包损坏文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36606696/

相关文章:

c++ - 用于进程/任务调度的简单离散事件模拟库(C++)?

java - 套接字未正确关闭

c++ - Recv方法使用

c# - tcp/ip 客户端服务器无法通过互联网工作

sockets - 无法使用 boost asio 设置 TCP 源端口

c++ - 将对虚类实现的引用作为线程参数传递

python - 使用 Cython 在 C++ 的 Python 代码中使用数据

c - Netfilter 内核模块拦截数据包并记录它们

c++ - 如何为我的 3d 曲线添加可变性 - openGL/C++ 中的球面坐标

c++ - getpeername() 不适用于与本地主机的连接