首页 \ 问答 \ Netty - UDP服务器(Netty - UDP server)

Netty - UDP服务器(Netty - UDP server)

我有一个基于UDP Netty的服务器。 它有一个SimpleChannelUpstreamHandler流水线,我重写messageReceived方法。

我需要不时写回一些信息。 我只能通过使用MessageEvent.getRemoteAddress()的套接字信息和MessageEvent.getRemoteAddress()的通道来完成此操作。 为了能够重复使用这些信息,我保存在一张静态地图中。

这将变成MessageEvent.getChannel().write("foo", MessageEvent.getRemoteAddress());

我所期望的是让MessageEvent.getChannel().getRemoteAddress()工作,事实并非如此。 它总是给我null

  1. 难道我做错了什么 ?
  2. 在保留某些成员的频道和远程地址的情况下,是否有更好的写回方式?

I am having an UDP Netty based server. It has a SimpleChannelUpstreamHandler pipelined where I override the messageReceived method.

I need to write back some information now and then. I could only do that by using the socket information from MessageEvent.getRemoteAddress(), and the channel from MessageEvent.getChannel(). In order to be able to reuse this information I keep in in a static map.

This turns into MessageEvent.getChannel().write("foo", MessageEvent.getRemoteAddress());

What I would have expected was to have MessageEvent.getChannel().getRemoteAddress() work, which is not the case. It always gives me null.

  1. Am I doing something wrong ?
  2. Is there a better way for writing back than keeping the channel and remote address in some member ?

原文:https://stackoverflow.com/questions/17321850
更新时间:2022-06-16 19:06

最满意答案

入口点RVA,入口点原始地址和图像基址以这种方式不相关。

图像库是“当它加载到存储器中时图像的第一个字节的首选地址”。 换句话说,假设没有冲突,它是加载时图像的虚拟地址。 如果在加载图像时存在地址冲突(例如,已经在重叠范围中加载了另一图像),则将为图像选择新的基地址。

RVA是相对虚拟地址。 它是“相对的”,因为它在实际加载图像时会发生变化。 它是未知基址的地址(例如,未加载图像时)。 加载映像后,RVA将成为虚拟地址(VA),即虚拟内存中的实际地址。

原始与RVA的区别在于对齐。 部分对齐(部分在加载到内存时对齐)以及文件对齐(部分中原始数据的对齐)。 这里的节对齐是0x1000,而文件对齐是0x200。

入口点RVA用于确定加载图像时入口点的VA(即入口点将位于虚拟地址EntryPoint (rva) + ImageBase )。 入口点原始地址是入口点所在文件的偏移量。

本文档对齐有很好的解释。


The entry point RVA, entry point raw address, and image base address are not related in that way.

The image base is the "preferred address of the first byte of the image when it is loaded in memory". In other words, it's the virtual address of the image when it gets loaded assuming there's not a conflict. If there is an address conflict when the image is loaded (e.g. another image is already loaded in an overlapping range), then a new base address will be chosen for the image.

An RVA is a relative virtual address. It is "relative" in the sense that it is changed when the image is actually loaded. It's the address when the base address is not known (e.g. when the image isn't loaded). Once the image is loaded, the RVA becomes a virtual address (VA), an actual address in virtual memory.

The raw vs. RVA distinction is due to alignment. There is section alignment (the alignment of the sections when they get loaded into memory) as well as file alignment (the alignment of the raw data in the sections). The section alignment here is 0x1000 while the file alignment is 0x200.

The entry point RVA is used to determine the VA of the entry point when the image is loaded (i.e. the entry point will be located at virtual address EntryPoint (rva) + ImageBase). The entry point raw address is the offset into the file where the entry point is located.

This document has a good explanation of alignment.

相关问答

更多
  • 必须通过al.exe链接al.exe才能创建可用的程序集。 链接器的工作是在程序集中生成元数据的最终版本。 独一无二的。 .netmodules must be linked by al.exe to create a usable assembly. It's the linker's job to generate the final version of the metadata in the assembly. The one and only.
  • 这是PE文件格式的一个很好的起点。 您可以从基地址P /调用ReadProcessMemory ,以将头复制到您的过程中。 你需要解析你读入各种PE头的内存。 第一个标题是IMAGE_DOS_HEADER ,它将指向IMAGE_NT_HEADERS 。 然后,您可以使用IMAGE_NT_HEADERS中的IMAGE_OPTIONAL_HEADER来查找二进制文件中IMAGE_EXPORT_DIRECTORY的位置。 This is a good starting point for the PE file ...
  • 这是一个很好的问题,并说明了Windows加载程序如何计算内存大小的一个非常重要的观点(或者你可能会说是怪癖)。 PE / COFF规范确实将VirtualSize描述为“加载到内存中时节的总大小”。 如果您认为total是包含该部分的REAL数据的总量,那么这在技术上是正确的,但它不是Windows为该部分分配的内存总量。 您会发现VirtualSize通常比Windows为内存中的部分分配的数量少,因为VirtualSize必须四舍五入到最近的内存对齐值(在PE映像中设置)。 换句话说,VirtualS ...
  • 入口点RVA,入口点原始地址和图像基址以这种方式不相关。 图像库是“当它加载到存储器中时图像的第一个字节的首选地址”。 换句话说,假设没有冲突,它是加载时图像的虚拟地址。 如果在加载图像时存在地址冲突(例如,已经在重叠范围中加载了另一图像),则将为图像选择新的基地址。 RVA是相对虚拟地址。 它是“相对的”,因为它在实际加载图像时会发生变化。 它是未知基址的地址(例如,未加载图像时)。 加载映像后,RVA将成为虚拟地址(VA),即虚拟内存中的实际地址。 原始与RVA的区别在于对齐。 部分对齐(部分在加载到内 ...
  • 您可以像这样计算PE头的总大小: sizeof(Signature) + sizeof(FileHeader) + sizeof(OptionalHeader) + sizeof(SectionTable) 文件头总是具有相同的大小,但OptionalHeader的大小可以不同,部分表大小也是如此。 OptionalHeader的大小存储在FileHeader.SizeOfOptionalHeader ,而section表大小等于FileHeader.NumberOfSections * sizeof(I ...
  • 我建议在创建过程时获取此信息。 您可以在创建新进程时通知PsSetCreateProcessNotifyRoutine(Ex) 。 当PE文件(包括进程'主可执行文件)映射到虚拟地址空间时, PsSetLoadImageNotifyRoutine通知您。 当进程完全初始化并运行时,从进程的内存中读取版本信息是一个坏主意。 该进程可以完全控制其PE文件映射,因此可以伪造版本信息。 更重要的是,您只能在低IRQL(PASSIVE_LEVEL)下访问用户模式内存。 可以在APC_LEVEL / DISPATCH_ ...
  • 你肯定是从错误的一端解决这个问题。 破解十六进制并不会让你得到你想要的东西,PE文件结构太复杂了。 你需要两件事。 Matt Pietrek的开创性文章是理解结构的必要读物。 在了解至少75%的代码之前,不要开始使用代码。 您需要Windows SDK。 include / winnt.h文件包含PE格式中使用的结构的声明。 它从_IMAGE_DOS_HEADER开始,这是文件的第一个块。 编写代码以从其声明中创建结构,这是获得有效可执行文件的唯一方法。 PS:您的十六进制转储挂起了试图查看您的问题的任何人 ...
  • 实际上,在我刚刚构建的可执行文件中,没有.idata部分。 使用PE Explorer,我们可以看到Import Table和IAT存储为.rdata部分的一部分。 (注意“指向目录”栏): 在Data Directories页面上,我们看到Import Table的虚拟地址是0x403354 。 这落在.rdata部分( 0x403000 - 0x403C00 )的范围内。 有趣的是(有点令人沮丧),IDA的PE加载器综合“创建”了一个实际上不存在于文件中的.idata部分: Indeed, in the ...
  • 是否真的是Windows操作系统仅为父可执行文件评估此标志的情况? 是。 是否完全忽略了所有DLL模块? 是。 那么,如果没有人在评估它,为什么我应该为DLL启用LAA链接器标志? 你不应该。 这样做毫无意义。 我记得以下内容:如果启用LAA的exe加载未编译为LAA的模块,是否有办法强制Windows发出警告? 不,那里没有。 问题是堆是进程广泛的。 它由所有模块共享。 你不能让一些人使用LAA堆而其他人不能。 所以只有可执行文件才有机会做出这个决定。 该标志采用PE文件格式,这对于DLL和EXE是常见的 ...
  • PE格式是Little Endian ,因此最不重要的字节是第一个。 PE format is Little Endian, so the least-significant byte is first.

相关文章

更多

最新问答

更多
  • 如何检索Ember.js模型的所有属性(How to retrieve all properties of an Ember.js model)
  • maven中snapshot快照库和release发布库的区别和作用
  • arraylist中的搜索元素(Search element in arraylist)
  • 从mysli_fetch_array中获取选定的值并输出(Get selected value from mysli_fetch_array and output)
  • Windows Phone上的可用共享扩展(Available Share Extensions on Windows Phone)
  • 如何在命令提示符下将日期设置为文件名(How to set file name as date in command prompt)
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • 从iframe访问父页面的id元素(accessing id element of parent page from iframe)
  • linux的常用命令干什么用的
  • Feign Client + Eureka POST请求正文(Feign Client + Eureka POST request body)
  • 怎么删除禁用RHEL/CentOS 7上不需要的服务
  • 为什么Gradle运行测试两次?(Why does Gradle run tests twice?)
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在android中的活动之间切换?(Switching between activities in android?)
  • Perforce:如何从Depot到Workspace丢失文件?(Perforce: how to get missing file from Depot to Workspace?)
  • Webform页面避免运行服务器(Webform page avoiding runat server)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 内存布局破解(memory layout hack)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • 我们可以有一个调度程序,你可以异步添加东西,但会同步按顺序执行吗?(Can we have a dispatcher that you can add things todo asynchronously but will be executed in that order synchronously?)
  • “FROM a,b”和“FROM a FULL OUTER JOIN b”之间有什么区别?(What is the difference between “FROM a, b” and “FROM a FULL OUTER JOIN b”?)
  • Java中的不可变类(Immutable class in Java)
  • bat批处理文件结果导出到txt
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • 德州新起点计算机培训学校主要课程有什么?
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • “latin1_german1_ci”整理来自哪里?(Where is “latin1_german1_ci” collation coming from?)