Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么应用程序在尝试使用SSL_write发送某些数据时挂起?_C++_Openssl - Fatal编程技术网

C++ 为什么应用程序在尝试使用SSL_write发送某些数据时挂起?

C++ 为什么应用程序在尝试使用SSL_write发送某些数据时挂起?,c++,openssl,C++,Openssl,我需要使用OpenSSL传输数据。但有些数据没有传输。 有两个文件包含数据。 dt1工作正常。但是当我的应用程序尝试发送dt2时,它挂起了 //服务器 #包括 #包括 #包括 #包括 #定义WINSOCKAPI_ #包括 #包括 #包括 #包括 int OpenListener(int端口) { 国际标准差; 地址中的结构sockaddr\u; sd=套接字(PF_INET,SOCK_STREAM,0); memset(&addr,0,sizeof(addr)); addr.sin_fami

我需要使用OpenSSL传输数据。但有些数据没有传输。
有两个文件包含数据。
dt1
工作正常。但是当我的应用程序尝试发送
dt2
时,它挂起了


//服务器
#包括
#包括
#包括
#包括
#定义WINSOCKAPI_
#包括
#包括
#包括
#包括
int OpenListener(int端口)
{
国际标准差;
地址中的结构sockaddr\u;
sd=套接字(PF_INET,SOCK_STREAM,0);
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
地址SINU port=htons(端口);
addr.sin\u addr.s\u addr=INADDR\u ANY;
如果(绑定(sd,(结构sockaddr*)和地址,sizeof(地址))!=0){
perror(“无法绑定端口”);
中止();
}
如果(听(sd,10)!=0){
perror(“无法配置侦听端口”);
中止();
}
返回sd;
}
SSL_CTX*InitServerCTX(无效)
{
const SSL_方法*方法;
SSL_CTX*CTX;
OpenSSL_添加_所有算法();
SSL_加载_错误_字符串();
方法=SSLv2_服务器_方法();
ctx=SSL\u ctx\u新(方法);
如果(ctx==NULL){
错误打印错误fp(stderr);
中止();
}
返回ctx;
}
无效加载证书(SSL_CTX*CTX、char*CertFile、char*KeyFile)
{
if(SSL\u CTX\u使用\u证书\u文件(CTX、CertFile、SSL\u文件类型\u PEM)h\u地址);
if(connect(sd,(struct sockaddr*)和addr,sizeof(addr))!=0){
闭式插座(sd);
perror(主机名);
中止();
}
返回sd;
}
int main()
{
const std::string&hostName=“localhost”;
const int port=7654;
WSADATA WSADATA;
WSAStartup(MAKEWORD(2,2)和wsaData);
SSL_库_init();
SSL_CTX*CTX=InitCTX();
int server=OpenConnection(hostName.c_str(),端口);
SSL*SSL=SSL_new(ctx);
SSL\u set\u fd(SSL,服务器);
如果(SSL_连接(SSL)=-1){
错误打印错误fp(stderr);
}
否则{
const int BUF_SIZE=0x100000;
std::字符串数据;
数据。调整大小(BUF_大小);
int n=SSL_read(SSL和数据[0],BUF_大小);
数据。调整大小(n);
SSL_write(SSL,&data[0],(int)data.size();
系统(“暂停”);
}
}

挂起表示客户端无法调用
SSL\u read
或不在那里。当服务器想要调用
SSL\u write
@doptimuprime客户端已到达SSL\u读取并接受数据时,检查客户端是否已到达
SSL\u读取
。但服务器上的SSL_写入挂起。然后确保客户端应保存所有数据。尽管我认为假设服务器在发送数据时被阻塞是愚蠢的,因为它的缓冲区被占用了。检查客户端必须接收的发送字节数。@doptimuprime dt2大小为71820。客户端SSL_读取收到32744。由于套接字被阻塞,如果所有数据的发送未完成,它将被阻塞。尝试部分发送数据(例如1kB的倍数,而不是一次发送)
// SERVER
#include <fstream>
#include <vector>
#include <WS2tcpip.h>
#include <Winsock2.h>
#define _WINSOCKAPI_
#include <windows.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/applink.c>

int OpenListener(int port)
{
    int sd;
    struct sockaddr_in addr;
    sd = socket(PF_INET, SOCK_STREAM, 0);
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        perror("can't bind port");
        abort();
    }
    if (listen(sd, 10) != 0) {
        perror("Can't configure listening port");
        abort();
    }
    return sd;
}

SSL_CTX* InitServerCTX(void)
{
    const SSL_METHOD *method;
    SSL_CTX *ctx;
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    method = SSLv2_server_method();
    ctx = SSL_CTX_new(method);
    if (ctx == NULL) {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        abort();
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        abort();
    }
    if (!SSL_CTX_check_private_key(ctx)) {
        fprintf(stderr, "Private key does not match the public certificate\n");
        abort();
    }
}

int main()
{
    SSL_CTX *ctx;
    int server;

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    SSL_library_init();

    ctx = InitServerCTX();
    LoadCertificates(ctx, "sert.crt", "sert.key");
    server = OpenListener(7654);

    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);

    int client = accept(server, (struct sockaddr*)&addr, &len);

    SSL *ssl;
    printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, client);

    if (SSL_accept(ssl) == -1) {
        ERR_print_errors_fp(stderr);
    }
    else {
        std::ifstream fin("dt1", std::ios::binary);
        std::string data((std::istreambuf_iterator<char>(fin)),
                                        std::istreambuf_iterator<char>());
        fin.close();

        //////////////////////////////////////////////
        SSL_write(ssl, &data[0], (int)data.size()); // dt1- good. data2 - hanging
        //////////////////////////////////////////////

        const int BUF_SIZE = 0x100000;
        std::string data1;
        data1.resize(BUF_SIZE);
        int n = SSL_read(ssl, &data1[0], BUF_SIZE);

        if (n >= 0) {
            data1.resize(n);
        }

        bool b = (data == data1);
    }

    SSL_free(ssl);
    closesocket(client);
}
// CLIENT
#include <string>
#include <vector>
#include <WS2tcpip.h>
#include <Winsock2.h>
#define _WINSOCKAPI_
#include <windows.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/applink.c>

SSL_CTX *InitCTX(void)
{
    const SSL_METHOD *method;
    SSL_CTX *ctx;
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    method = SSLv2_client_method();
    ctx = SSL_CTX_new(method);
    if (ctx == NULL) {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}

int OpenConnection(const char *hostName, int port)
{
    struct hostent *host;
    struct sockaddr_in addr;
    if ((host = gethostbyname(hostName)) == NULL) {
        perror(hostName);
        abort();
    }
    int sd = socket(PF_INET, SOCK_STREAM, 0);
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = *(long*)(host->h_addr);
    if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        closesocket(sd);
        perror(hostName);
        abort();
    }
    return sd;
}

int main()
{
    const std::string &hostName = "localhost";
    const int port = 7654;

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    SSL_library_init();

    SSL_CTX *ctx = InitCTX();
    int server = OpenConnection(hostName.c_str(), port);
    SSL *ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    if (SSL_connect(ssl) == -1) {
        ERR_print_errors_fp(stderr);
    }
    else {
        const int BUF_SIZE = 0x100000;
        std::string data;
        data.resize(BUF_SIZE);
        int n = SSL_read(ssl, &data[0], BUF_SIZE);
        data.resize(n);

        SSL_write(ssl, &data[0], (int)data.size());

        system("pause");
    }
}