我设计了一个简单的数据报和数据包结构。我还尝试编写函数,该函数会将数据报转换为数据包,并将数据报转换为数据报。
但是,在测试时,我发现有问题。该代码应该两次显示数字134,而不仅仅是一次。也就是说,SessionID
在d1
和d2
中应该相同,但不相同。有什么想法吗?
#include <stdint.h>
#include <ctime>
#include <random>
//Packet
//a = [00000000] 2 bits Operation, 6 bits of first number [00|000000]
//b = [00000000] 8 bits of first number [00000000]
//c = [00000000] 2 bits of fist number and six bits of second number [00|000000]
//d = [00000000] 8 bits of second number [00000000]
//e = [00000000] 2 bits of second number 3 bits of Status and 3 bits of 3 bits of SessionID[00|000|000]
//f = [00000000] 5 bits of SessionID and 3 bits of answer [00000000]
struct Packet { //[00000000|00000000|00000000|00000000|00000000|00000000]
uint8_t a, b, c, d, e, f;
Packet() {
a = 0b00000000;
b = 0b00000000;
c = 0b00000000;
d = 0b00000000;
e = 0b00000000;
f = 0b00000000;
}
};
//Create our packet
struct Datagram { //[00|0000000000000000|0000000000000000|000|00000000|000]
uint8_t Operation, Status, SessionID, Answer;
uint16_t FirstNumber, SecondNumber;
Datagram() {
this->Operation = 0b00000000;
this->FirstNumber = 0b0000000000000000;
this->SecondNumber = 0b0000000000000000;
this->Status = 0b00000000;
this->SessionID = 0b00000000;
this->Answer = 0b00000000;
}
};
//Change Datagram to Packet
Datagram ChangeToDatagram(Packet p0) {
Datagram result;
result.Operation = p0.a & 0b11000000;
result.Operation >>= 6;
uint8_t x1 = 0;
x1 = p0.a & 0b00111111;
uint8_t y1 = 0;
y1 = p0.b & 0b11111111;
uint8_t z1 = 0;
z1 = p0.c & 0b11000000;
result.FirstNumber = x1 | y1 | z1;
result.FirstNumber <<= 2;
uint8_t x2 = 0;
x2 = p0.c & 0b00111111;
uint8_t y2 = 0;
y2 = p0.d & 0b11111111;
uint8_t z2 = 0;
z2 = p0.e & 0b11000000;
result.SecondNumber = x2 | y2 | z2;
result.SecondNumber <<= 2;
result.Status = p0.e & 0b00111000;
result.Status >>= 3;
uint8_t x3 = 0;
x3 = p0.e & 0b00000111;
uint8_t y3 = 0;
y3 = p0.f & 0b11111000;
result.SessionID = x3 | y3;
result.SessionID >>= 3;
result.Answer = p0.f & 0b00000111;
return result;
}
//Change Packet to Datagram
Packet ChangeToPacket(Datagram d) {
Packet result;
result.a = d.Operation <<= 6;
uint16_t x1 = 0;
x1 = d.FirstNumber & 0b1111111111111111;
x1 >>= 10;
x1 <<= 8; // <<=10
result.a = result.a | x1;
uint16_t y1 = 0;
y1 = d.FirstNumber & 0b1111111111111111;
y1 <<= 6;
y1 >>= 6;
y1 >>= 2;
y1 <<= 2;
result.b = y1;
uint16_t z1 = 0;
z1 = d.FirstNumber & 0b1111111111111111;
z1 <<= 14;
//z1 >>= 14;
uint16_t x2 = 0;
x2 = d.SecondNumber & 0b1111111111111111;
x2 >>= 10;
x2 <<= 8; //<<= 10;
result.c = z1 | x2;
uint16_t y2 = 0;
y2 = d.SecondNumber & 0b1111111111111111;
y2 <<= 6;
y2 >>= 6;
y2 >>= 2;
y2 <<= 2;
result.d = y2;
uint16_t z2 = 0;
z2 = d.SecondNumber & 0b1111111111111111;
z2 <<= 14;
//z2 >>= 14;
uint8_t x3 = 0;
x3 = d.Status <<= 3;
uint8_t x4 = 0;
x4 = d.SessionID & 0b11111111;
x4 >>= 5;
result.e = z2 | x3 | x4 ;
uint8_t y4 = 0;
y4 = d.SessionID & 0b11111111;
y4 <<= 3;
uint8_t x5 = 0;
x5 = d.Answer;
result.f = y4 | x5;
return result;
}
int main()
{
Datagram d1,d2;
Packet p1,p2;
d1.SessionID = 134;
p1 = ChangeToPacket(d1);
d2 = ChangeToDatagram(p1);
printf("%d %d\n", d1.SessionID, d2.SessionID);
return 0;
}
查看您如何重建SessionID
值。您将丢弃从p0.e
中提取的3位,这些3位属于SessionID
值的高3位。
适当的重建是
result.SessionID = (y3 >> 3) | (x3 << 5);
很难阅读和调试此代码,我注意到了一些错误,如:
result.a = d.Operation <<= 6;
但更容易将其更改为:
//Change Packet to Datagram
Packet ChangeToPacket(Datagram d) {
Packet result;
result.a = ((d.Operation & 0b11) << 6) | ((d.FirstNumber >> 10) & 0b111111); // 2 bits of operation and 6 bits of first number
result.b = (d.FirstNumber >> 2) & 0b11111111; // 8 bits of first number
result.c = ((d.FirstNumber & 0b11) << 6) | ((d.SecondNumber >> 10) & 0b111111); // 2 bits of first number and 6 bits of second number
result.d = (d.SecondNumber >> 2) & 0b11111111; // 8 bits of second number
result.e = ((d.SecondNumber & 0b11) << 6) | ((d.Status & 0b111) << 3) | ((d.SessionID & 0b11111111) >> 5); // 2 bits of second number and 3 bits of status and 3 bits of session
result.f = ((d.SessionID & 0b11111) << 3) | (d.Answer & 0b111); // 5 bits of session and 3 bits of answer
return result;
}
//Change Datagram to Packet
Datagram ChangeToDatagram(Packet p0) {
Datagram result;
result.Operation = (p0.a & 0b11000000) >> 6;
result.FirstNumber = ((p0.a & 0b111111) << 10) | (p0.b << 2) | ((p0.c & 0b11000000) >> 6);
result.SecondNumber = ((p0.c & 0b111111) << 10) | (p0.d << 2) | ((p0.e & 0b11000000) >> 6);
result.Status = (p0.e & 0b111000) >> 3;
result.SessionID = ((p0.e & 0b111) << 5) | ((p0.f & 0b11111000) >> 3);
result.Answer = p0.f & 0b111;
return result;
}
这样,您可以查看每个操作并确认它们正确无误