在将问题解决到this question之后,我继续扩展此版本的代码,以将以前的模板版本中的数据字段的并集与该版本合并在一起,到目前为止,我已经做到了:
main.cpp
%% No cached client session
update handshake state: client_hello[1]
upcoming handshake states: server_hello[2]
*** ClientHello, TLSv1
RandomCookie: GMT: 1540414784 bytes = { 244, 150, 37, 122, 161, 146, 112, 42, 146, 1, 157, 89, 176, 65, 143, 62, 197, 121, 235, 202, 6, 196, 139, 184, 79, 38, 200, 208 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension extended_master_secret
***
[write] MD5 and SHA1 hashes: len = 111
0000: 01 00 00 6B 03 01 5C D1 DD 40 F4 96 25 7A A1 92 ...k..\..@..%z..
0010: 70 2A 92 01 9D 59 B0 41 8F 3E C5 79 EB CA 06 C4 p*...Y.A.>.y....
0020: 8B B8 4F 26 C8 D0 00 00 1E C0 0A C0 14 00 35 C0 ..O&..........5.
0030: 05 C0 0F 00 39 00 38 C0 09 C0 13 00 2F C0 04 C0 ....9.8...../...
0040: 0E 00 33 00 32 00 FF 01 00 00 24 00 0A 00 16 00 ..3.2.....$.....
0050: 14 00 17 00 18 00 19 00 09 00 0A 00 0B 00 0C 00 ................
0060: 0D 00 0E 00 16 00 0B 00 02 01 00 00 17 00 00 ...............
main, WRITE: TLSv1 Handshake, length = 111
[Raw write]: length = 116
0000: 16 03 01 00 6F 01 00 00 6B 03 01 5C D1 DD 40 F4 ....o...k..\..@.
0010: 96 25 7A A1 92 70 2A 92 01 9D 59 B0 41 8F 3E C5 .%z..p*...Y.A.>.
0020: 79 EB CA 06 C4 8B B8 4F 26 C8 D0 00 00 1E C0 0A y......O&.......
0030: C0 14 00 35 C0 05 C0 0F 00 39 00 38 C0 09 C0 13 ...5.....9.8....
0040: 00 2F C0 04 C0 0E 00 33 00 32 00 FF 01 00 00 24 ./.....3.2.....$
0050: 00 0A 00 16 00 14 00 17 00 18 00 19 00 09 00 0A ................
0060: 00 0B 00 0C 00 0D 00 0E 00 16 00 0B 00 02 01 00 ................
0070: 00 17 00 00 ....
[Raw read]: length = 5
0000: 15 03 03 00 02 .....
[Raw read]: length = 2
0000: 02 28 .(
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
Handshake failed: TLSv1, error = Received fatal alert: handshake_failure
Exception in thread "main" javax.naming.CommunicationException: Failed to initialize JNDI context, tried 2 time or times totally, the interval of each time is 0ms.
t3s://xyz:1234: Destination 192.168.16.104, 1234 unreachable.; nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure; No available router to destination.; nested exception is:
java.rmi.ConnectException: No available router to destination. [Root exception is java.net.ConnectException: t3s://xyz:1234: Destination 192.168.16.104, 1234 unreachable.; nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure; No available router to destination.; nested exception is:
java.rmi.ConnectException: No available router to destination.]
at weblogic.jndi.WLInitialContextFactoryDelegate.throwRetryException(WLInitialContextFactoryDelegate.java:467)
at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:403)
at weblogic.jndi.Environment.getContext(Environment.java:351)
at weblogic.jndi.Environment.getContext(Environment.java:320)
at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:119)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:216)
注册。h
#include <iostream>
#include <type_traits>
#include "Register.h"
int main() {
using namespace vpc;
std::cout << std::boolalpha;
std::cout << "std::bitset<64> is trivially copyable "
<< std::is_trivially_copyable<std::bitset<64>>::value << '\n'
<< "QWord is trivially copyable "
<< std::is_trivially_copyable<QWord>::value << '\n'
<< "DWord is trivially copyable "
<< std::is_trivially_copyable<DWord>::value << '\n'
<< "Word is trivially copyable "
<< std::is_trivially_copyable<Word>::value << '\n'
<< "Byte is trivially copyable "
<< std::is_trivially_copyable<Byte>::value << '\n'
// << "Bits is trivially copyable "
//<< std::is_trivially_copyable<Bits>::value << '\n'
<< "My Register is trivially copyable "
<< std::is_trivially_copyable<Register>::value << "\n\n";
std::cout << "sizeof(std::bitset<Byte>) = " << sizeof(Byte) << " bytes\n";
std::cout << "sizeof(std::bitset<Word>) = " << sizeof(Word) << " bytes\n";
std::cout << "sizeof(std::bitset<DWord>) = " << sizeof(DWord) << " bytes\n";
std::cout << "sizeof(std::bitset<QWord>) = " << sizeof(QWord) << " bytes\n";
std::cout << "sizeof(Register) = " << sizeof(Register) << " bytes\n\n";
Register r;
std::cout << "sizeof(Register::byte) = " << sizeof(r.byte) << " bytes\n";
std::cout << "sizeof(Register::Byte) = " << sizeof(r.byte) / sizeof(r.byte[0]) << " bytes\n";
std::cout << "sizeof(Register::word) = " << sizeof(r.word) << " bytes\n";
std::cout << "sizeof(Register::Word) = " << sizeof(r.word) / sizeof(r.word[0]) << " bytes\n";
std::cout << "sizeof(Register::dword) = " << sizeof(r.dword) << " bytes\n";
std::cout << "sizeof(Register::DWord) = " << sizeof(r.dword) / sizeof(r.dword[0]) << " bytes\n";
std::cout << "sizeof(Register::value) = " << sizeof(r.value) << " bytes\n";
std::cout << "sizeof(Register) = " << sizeof(r) << " bytes\n\n";
r.value = 0xFFFFFFFFFFFFFFFF;
std::cout << "value = " << r.value.to_ullong() << '\n' << r.value << '\n';
for (std::uint16_t i = 0; i < 8; i++) {
std::cout << "byte_" << i << " : " << r.byte[i] << '\n';
}
return EXIT_SUCCESS;
}
Register.cpp
#pragma once
#include <algorithm>
#include <bitset>
#include <string>
#include <vector> // include for typedefs below.
namespace vpc {
typedef std::int8_t i8;
typedef std::int16_t i16;
typedef std::int32_t i32;
typedef std::int64_t i64;
const std::uint16_t BYTE = 0x08;
const std::uint16_t WORD = 0x10;
const std::uint16_t DWORD = 0x20;
const std::uint16_t QWORD = 0x40;
typedef std::bitset<BYTE> Byte;
typedef std::bitset<WORD> Word;
typedef std::bitset<DWORD> DWord;
typedef std::bitset<QWORD> QWord;
struct Register {
union {
QWord value{ 0 };
union {
DWord dword[2];
struct {
DWord dword0;
DWord dword1;
};
};
union {
Word word[4];
struct {
Word word0;
Word word1;
Word word2;
Word word3;
};
};
union {
Byte byte[8];
struct {
Byte byte0;
Byte byte1;
Byte byte2;
Byte byte3;
Byte byte4;
Byte byte5;
Byte byte6;
Byte byte7;
};
};
};
Register() : value{ 0 } {}
};
Register reverseBitOrder(Register& reg, bool copy = false);
} // namespace vpc
输出
#include "Register.h"
namespace vpc {
Register reverseBitOrder(Register& reg, bool copy) {
auto str = reg.value.to_string();
std::reverse(str.begin(), str.end());
if (copy) { // return a copy
Register cpy;
cpy.value = QWord(str);
return cpy;
}
else {
reg.value = QWord(str);
return {};
}
}
} // namespace vpc
查看打印出的数据std::bitset<64> is trivially copyable true
QWord is trivially copyable true
DWord is trivially copyable true
Word is trivially copyable true
Byte is trivially copyable true
My Register is trivially copyable true
sizeof(std::bitset<Byte>) = 4 bytes
sizeof(std::bitset<Word>) = 4 bytes
sizeof(std::bitset<DWord>) = 4 bytes
sizeof(std::bitset<QWord>) = 8 bytes
sizeof(Register) = 32 bytes
sizeof(Register::byte) = 16 bytes
sizeof(Register::Byte) = 4 bytes
sizeof(Register::word) = 16 bytes
sizeof(Register::Word) = 4 bytes
sizeof(Register::dword) = 8 bytes
sizeof(Register::DWord) = 2 bytes
sizeof(Register::value) = 8 bytes
sizeof(Register) = 32 bytes
value = 18446744073709551615
1111111111111111111111111111111111111111111111111111111111111111
byte_0 : 11111111
byte_1 : 11111111
byte_2 : 11001100
byte_3 : 11001100
byte_4 : 11001100
byte_5 : 11001100
byte_6 : 11001100
byte_7 : 11001100
类型的大小后,将它们与作为联合中的结构成员的实际大小进行比较。我正在尝试弄清这里到底发生了什么。
我不确定我是否正确执行sizeof计算,是否与bitset
的内部存储有关?我试图了解并集上下文中的数据对齐方式作为基础类型为bitset
类型的结构的成员。从标题中您可以看到它们有4种变体:std::bitset
,bitset<8> = Byte
,bitset<16> = Word
和bitset<32> = DWord
从本质上讲,应该对它们进行可分割的映射:
bitset<64> = QWord
因此,当我尝试像这样在联合体中使用它们时:
// each [] = 1 byte or 8 bits for simplicity
bitset<64> = [] [] [] [] [] [] [] []
bitset<32> = [] [] [] []
bitset<16> = [] []
bitset<8> = []
我认为通过使用在联合上方显示的模式,我可以将数据打包为字节大小对齐方式:
union {
QWord q;
union {
DWord d[2];
struct {
DWord d_0;
DWord d_1;
};
};
union {
Word w[4];
struct {
Word w_0;
Word w_1;
Word w_2;
Word w_3;
};
};
union {
Byte b[8];
struct {
Byte b_0;
Byte b_1;
Byte b_2;
Byte b_3;
Byte b_4;
Byte b_5;
Byte b_6;
Byte b_7;
};
};
};
但是,这似乎并没有像我期望的那样发生。
我的总体目标是模拟上面所表达的模式,从而使寄存器的基本大小为64位或8字节宽,并且通过使用并集,我将能够从中访问子字节,字或dword。完整的qword。
请您能详细说明我在这里缺少的内容吗?我不确定// each inner [] = 1 byte or 8 bits
// and each outer [] = index into array
0 1 2 3 4 5 6 7
value = [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
0 1
dword[2] = [[] [] [] []], [[] [] [] []]
0 1 2 3
word[4] = [[] []], [[] []], [[] []], [[] []]
0 1 2 3 4 5 6 7
byte[8] = [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]] [[ ]]
是否与内存中的存储方式有关,是否与结构对齐有关,或者是否与联合本身打交道。
答案 0 :(得分:1)
您想要的东西无法以您想要的方式完成。 std::bitset
不保证其大小,因此不期望bitset<8>
具有一个字节的大小。如果这些bitset
的成员不是活动的工会成员,则您也无法访问它们。
您想要做的是:
uint64_t
。uint64_t
的比特的各个子集。因此只需实现那个。您所需要的不是bitset
,而是一种位范围视图类型,它使您可以将uint64_t
中的任何连续位序列解释和操纵为一个范围。基本上,您需要bitset
的接口,但是要通过对存储(以及该存储的特定范围)的引用来实现,而不是通过成为。您不存储这些范围;您可以根据要求生成范围。
答案 1 :(得分:0)
语言标准中没有规定bitset
如何在内部处理存储的内容。我研究的一种实现使用unsigned long
数组存储32个或更少的位(unsigned long long
则存储32个以上)。这样做可能是为了提高效率。
使用这种存储方案,即使不使用全部Byte
,Word
和DWord
类型,它们都将占用四个字节。将这些数组存储在较大的联合中将导致联合的大小增加,因为每个位集中都有未使用的字节。
为了消除这些未使用的字节,您将不得不使用其他内容。