- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个函数来解析 20 字节长的 IP 头缓冲区:
void parseIp(struct ipHeader *ip, const void *buffer)
{
uint8_t* b = buffer;
// memcpy(b,buffer,20);
ip->version = (b[0] & 0xf0) >> 4;
ip->ihl = (b[0] & 0x0f);
ip->dscp = (b[1] & 0xfC)>>2;
ip->ecn = (b[1] & 0x3);
unsigned short l = (b[2] << 8) | b[3];
printf("%d\n",l);
ip->length = l;
ip->identification = (b[4] << 0xFF) | b[5];
}
结构ipHeader:
struct ipHeader {
int version;
int ihl;
int dscp;
int ecn;
unsigned short length;
unsigned short identification;
int flags;
int fragment_offset;
int time_to_live;
int protocol;
unsigned short header_checksum;
unsigned char source_ip[4];
unsigned char destination_ip[4];
};
现在代码将 l 打印为 467,这是正确的,但由于此 l 已分配给结构字段长度,因此它更改为 54017。我完全不明白发生了什么。我添加了变量 l 以确保不会发生溢出或类型转换错误,但它仍然会发生变化。
这是学校作业的一部分,所以我无法更改结构。
编辑完整代码:
#include <stdio.h>
#include <arpa/inet.h>
#include "ipheader.h"
/* Parses the given buffer into an IP header structure.
*
* Parameters:
* ip: pointer to the IP header structure that will be filled based
* on the data in the buffer
* buffer: buffer of 20 bytes that contain the IP header. */
void parseIp(struct ipHeader *ip, const void *buffer)
{
uint8_t* b = buffer;
// memcpy(b,buffer,20);
ip->version = (b[0] & 0xf0) >> 4;
ip->ihl = (b[0] & 0x0f);
ip->dscp = (b[1] & 0xfC)>>2;
ip->ecn = (b[1] & 0x3);
unsigned short l = (b[2] << 8) | b[3];
printf("%d\n",l);
ip->length = l;
ip->identification = (b[4] << 8) | b[5];
}
/* Builds a 20-byte byte stream based on the given IP header structure
*
* Parameters:
* buffer: pointer to the 20-byte buffer to which the header is constructed
* ip: IP header structure that will be packed to the buffer */
void sendIp(void *buffer, const struct ipHeader *ip)
{
}
/* Prints the given IP header structure */
void printIp(const struct ipHeader *ip)
{
/* Note: ntohs below is for converting numbers from network byte order
to host byte order. You can ignore them for now
To be discussed further in Network Programming course... */
printf("version: %d ihl: %d dscp: %d ecn: %d\n",
ip->version, ip->ihl, ip->dscp, ip->ecn);
printf("length: %d id: %d flags: %d offset: %d\n",
ntohs(ip->length), ntohs(ip->identification), ip->flags, ip->fragment_offset);
printf("time to live: %d protocol: %d checksum: 0x%04x\n",
ip->time_to_live, ip->protocol, ntohs(ip->header_checksum));
printf("source ip: %d.%d.%d.%d\n", ip->source_ip[0], ip->source_ip[1],
ip->source_ip[2], ip->source_ip[3]);
printf("destination ip: %d.%d.%d.%d\n", ip->destination_ip[0],
ip->destination_ip[1],
ip->destination_ip[2], ip->destination_ip[3]);
}
/* Shows hexdump of given data buffer */
void hexdump(const void *buffer, unsigned int length)
{
const unsigned char *cbuf = buffer;
unsigned int i;
for (i = 0; i < length; ) {
printf("%02x ", cbuf[i]);
i++;
if (!(i % 8))
printf("\n");
}
}
struct ipHeader {
int version;
int ihl;
int dscp;
int ecn;
unsigned short length;
unsigned short identification;
int flags;
int fragment_offset;
int time_to_live;
int protocol;
unsigned short header_checksum;
unsigned char source_ip[4];
unsigned char destination_ip[4];
};
void parseIp(struct ipHeader *ip, const void *buffer);
void sendIp(void *buffer, const struct ipHeader *ip);
void printIp(const struct ipHeader *ip);
void hexdump(const void *buffer, unsigned int length);
#include <arpa/inet.h>
#include "ipheader.h"
int main()
{
/* Feel free to modify this function to test different things */
unsigned char bytes[] = {
0x45, 0x00, 0x01, 0xd3, 0xda, 0x8d, 0x40, 0x00,
0x40, 0x06, 0x8c, 0xd5, 0xc0, 0xa8, 0x01, 0x46,
0x6c, 0xa0, 0xa3, 0x33 };
struct ipHeader ip;
parseIp(&ip, bytes);
printIp(&ip);
struct ipHeader ipfields = {
4, // version
28, // ihl
4, // dscp
0, // ecn
htons(1500), // length
htons(1234), // id
1, // flags
1024, // offset
15, // time_to_live
33, // protocol
htons(0x1234), // checksum (invalid)
{1, 2, 3, 4}, // source IP
{5, 6, 7, 8} // destination IP
};
unsigned char sendbuf[20];
sendIp(sendbuf, &ipfields);
hexdump(sendbuf, sizeof(sendbuf));
}
最佳答案
对于给定的输入:
unsigned char bytes[] = { 0x45, 0x00, 0x01, 0xd3, 0xda,
然后是代码:
unsigned short l = (b[2] << 8) | b[3];
产生l
值为 467
.
你在你的问题中说,“因为这个 l 被分配给它更改为 54017 的结构字段长度。”。然而,事实并非如此。如果您在现有 ip->length = l;
之后立即添加一行:
printf("%d\n", ip->length);
你仍然会看到 467
.
我猜你提到的问题是你的 printIp
函数打印 54017
.这是因为那个函数不打印ip->length
.它打印出 ntohs(ip->length)
. ntohs
宏将值从 567
更改为至 54017
.
要解决此问题,请更改 printIp
打印功能 ip->length
,而不是 ntohs(ip->length)
.
删除另一个ntohs
也从该函数调用,并删除 htons
根据您对 ipfields
的定义.整数应该以 host 顺序(即 native 顺序)存储在 struct ipHeader
中。 ,并在 unsigned char
中以 n 网络顺序(即大端)存储缓冲区。
可移植性说明 1:从技术上讲,您应该使用 %hu
作为这两个格式说明符 printf
语句,因为参数类型是 unsigned short
.
可移植性说明 2: l == 467
不管int
大小,与迄今为止一些评论/答案中的建议相反。但要支持 b[2]
的值大于 0x7F
在具有 16 位 int
的系统上运行时, 你应该写 ((unsigned)b[2] << 8) | b[3]
.
可移植性说明 3:最好使用 uint16_t
而不是 unsigned short
因为现在有 32 位的系统 unsigned short
.如果这样做,printf 格式说明符是 "%"PRI16u
您可能需要 #include <inttypes.h>
关于c - 分配给结构字段时无符号短更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36284195/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!