吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1180|回复: 3
收起左侧

[求助] 最近在学C/C++网络编程,碰到一个问题,百思不得其解,希望大佬们指点一下

[复制链接]
alcule 发表于 2021-3-8 22:40
[C++] 纯文本查看 复制代码
#include<iostream>
#include<Winsock2.h>
#include<WS2tcpip.h>
#include<string>
#include<sstream>
#include<openssl/ssl.h>
#include<openssl/err.h>



#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"libssl.lib")
#pragma comment(lib,"libcrypto.lib")

using namespace std;




string Utf8ToGbk(const char* utf8) {

	int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);

	wchar_t* wstr = new wchar_t[len + (int64_t)1];
	memset(wstr, 0, len + (int64_t)1);
	MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
	len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + (int64_t)1];
	memset(str, 0, len + (int64_t)1);
	WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return str;
}


int main() {

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
	const SSL_METHOD* meth = SSLv23_client_method();

	SSL_CTX* ctx = SSL_CTX_new(meth);

	if (ctx == NULL) {

		ERR_print_errors_fp(stderr);
		cout << "ctx error!" << endl;
		return -1;
	}


	WSADATA wsadata;
	ADDRINFO* res, * cur;
	ADDRINFO hints;
	SOCKADDR_IN* addr;

	memset(&hints, 0, sizeof(ADDRINFO));

	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) {

		cout << "wsastartup error" << endl;

		return -1;
	}

	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;

	getaddrinfo("www.baidu.com", "HTTP", &hints, &res);

	cur = res;

	addr = (SOCKADDR_IN*)res->ai_addr;

	addr->sin_port = htons(443);

	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	if (sock == INVALID_SOCKET) {

		cout << "socket error" << endl;
		
		return -1;
	}

	if (connect(sock, (SOCKADDR*)addr, sizeof(*addr)) == SOCKET_ERROR) {

		cout << "connect error" << endl;

		return -1;
	}

	int ret;

	SSL* ssl = SSL_new(ctx);
	
	if (ssl == NULL) {

		cout << "ssl error" << endl;

		return -1;
	}

	SSL_set_fd(ssl, sock);
	
	ret = SSL_connect(ssl);

	if (ret == -1) {

		cout << "ssl_connect error " << endl;

		return -1;
	}


	stringstream stream;

	stream << "GET / HTTP/1.1\r\n";
	stream << "Accept: */*\r\n";
	stream << "Accept-Language: zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3\r\n";
	stream << "Connection: close\r\n";
	stream << "Host: www.baidu.com\r\n";
	stream << "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134\r\n";
	stream << "\r\n";

	string request = stream.str();

	ret = SSL_write(ssl, request.c_str(), request.size());

	if (ret == -1) {

		cout << "ssl_writ error" << endl;

		return -1;
	}

	char pageBuf[1024];

	string s;

	while (true) {

		if ((ret = SSL_read(ssl, pageBuf, 1023)) <= 0) {
			cout << ret;
			break;
		}

		s += Utf8ToGbk(pageBuf);
	}


	cout << s << endl;
	

	SSL_shutdown(ssl);
	SSL_free(ssl);
	SSL_CTX_free(ctx);
	closesocket(sock);
	freeaddrinfo(cur);
	WSACleanup();

}


这段代码是获取百度首页源码的,当我调用Utf8ToGbk时候获取的源码差两三行,ssl_recv最后一次返回值是0,不调用的时候获取的源码只有不到一半,ssl_recv的最后一次返回值是-1.

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| alcule 发表于 2021-3-8 22:41
希望大佬帮我解答一下。我感觉和ssl的缓冲区有关系,但我百度谷歌好久也没找到相关的问题和解决办法
cpj1203 发表于 2021-3-8 23:31
Eaglecad 发表于 2021-3-9 00:17
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 06:36

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表