通过套接字发送固定阵列与动态阵列

时间:2017-10-13 05:36:12

标签: c++ arrays sockets bignum

我正在尝试通过套接字发送BIGNUM(来自openssl / bn.h),但它的行为很奇怪。

我使用BN_bn2bin()将BIGNUM转换为unsigned char的数组,并使用send()通过套接字发送它。但客户收到的内容已损坏。为什么呢?

这是一个最小的工作样本:

server.cpp

#include <iostream>
#include <netinet/in.h>
#include <cstring>
#include <cstdlib>
#include <openssl/bn.h>
using namespace std;
int main() {
    // Set up
    int result;
    int opt_val = 1;
    int port = 12345;

    int listen_sock;
    int peer_sock;

    struct sockaddr_in address;

    listen_sock = socket(AF_INET, SOCK_STREAM, 0);

    memset(&address, 0, sizeof(address));

    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    address.sin_addr.s_addr = INADDR_ANY;

    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));

    result = bind(listen_sock, (struct sockaddr*)&address, sizeof(address));
    if (result != 0) {
        cerr << "bind() failed." << endl;
        exit(result);
    }

    result = listen(listen_sock, 5);
    if (result !=  0) {
        cerr << "listen() failed." << endl;
        exit(result);
    }

    size_t size = sizeof(address);
    peer_sock = accept(listen_sock, (struct sockaddr*)&address, (socklen_t *)&size);
    if (peer_sock < 0) {
        cerr << "accept() failed." << endl;
        exit(result);
    }

    ////////////////////////////////
    // Prepare BIGNUM
    BIGNUM* bn = BN_new();
    BN_rand(bn, 1024, 0, 0);
    size = BN_num_bytes((const BIGNUM*)bn);

    // Send using fixed array
    unsigned char fixed[size];
    BN_bn2bin((const BIGNUM*)bn, fixed);

    // Send using dynamic array
    unsigned char *dynamic;
    dynamic = new unsigned char[size];
    BN_bn2bin((const BIGNUM*)bn, dynamic);

    // First let's compare
    if ( memcmp(fixed, dynamic, size) != 0) {
        cout << "Fixed and dynamic do not equal" << endl;
        exit(-1);
    }

    // Then let's send two arrays
    send(peer_sock, &size, sizeof(size), MSG_MORE);
    send(peer_sock, fixed, size, MSG_MORE);
    send(peer_sock, dynamic, size, MSG_MORE);

}

client.cpp

#include <netinet/in.h>
#include <iostream>
#include <netdb.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <openssl/bn.h>
#include <cstring>

using namespace std;

int main() {

    struct addrinfo* res;
    struct sockaddr_in address;
    int peer_port = 12345;
    int self_sock;
    string peer_ip = "127.0.0.1";
    address.sin_family = AF_INET;
    address.sin_port = htons(peer_port);

    int result = getaddrinfo((const char*)peer_ip.c_str(), NULL, NULL, &res);
    if (result != 0) {
        std::cerr << "Peer hostname invalid." << std::endl;
        exit(-1);
    }
    freeaddrinfo(res);
    inet_pton(AF_INET, (const char*)peer_ip.c_str(), &(address.sin_addr));
    self_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (::connect(self_sock, (struct sockaddr*)&address, sizeof(address)) != 0) {
        std::cerr << "connect() failed." << std::endl;
        exit(-1);
    }


    int size;
    recv(self_sock, &size, sizeof(size), 0);
    // Receive fixed array
    unsigned char fixed[size];
    unsigned char* dynamic = new unsigned char[size];
    recv(self_sock, fixed, size, 0);
    recv(self_sock, dynamic, size, 0);

    if (memcmp(fixed, dynamic, size) != 0) {
        cerr << "client: fixed and dynamic are different!" << endl;
        exit(-1);
    }

    BIGNUM* bn_fixed = BN_new();
    BIGNUM* bn_dynamic = BN_new();
    BN_bin2bn((const unsigned char*)fixed, size, bn_fixed);
    BN_bin2bn((const unsigned char*)dynamic, size, bn_dynamic);
    if (BN_cmp((const BIGNUM*)bn_fixed, (const BIGNUM*)bn_dynamic) != 0) {
        cerr << "bn_fixed and bn_dynamic are different!" << endl;
        exit(-1);
    }

    return 0;
}

使用g++ -o <server/client> <server.cpp/client.cpp> -lssl -lcrypto

构建两者

我使用memcmp并验证了记忆fixeddynamic指向彼此,但fixeddynamic客户收到的是完全不同于原始信息。我怀疑这可能是因为我使用的是localhost,但是当我尝试使用两台独立的机器时,它仍然会发生。

0 个答案:

没有答案