我正在制作一个程序,使用C套接字与某些患者监视器进行通信.我正在使用无连接套接字(UDP)与设备通信.但是我的计算机和设备之间存在字节不匹配,到目前为止,我这样做是为了从患者监视器获得解析响应:
recvfrom(int socket, char *buffer, size_t length, int flags,
struct sockaddr *address, socklen_t *address_len);
Run Code Online (Sandbox Code Playgroud)
然后我直接将缓冲区转换为结构并使用ntohs和ntohl来更改字节顺序,例如:
struct A * a = (struct A *)buffer;
Struct A b;
b.v1 = ntohs(a->v1);
b.v2 = ntohl(a->v2);
Run Code Online (Sandbox Code Playgroud)
在通过互联网阅读几个例子之后,我发现由于编译器依赖填充,这可能是错误的方法.但我不确定.我需要简单的方法来将缓冲区解组为具有正确endian的C结构.我收到的结构可能是不可预测的长度,也很复杂.我需要快速简便的方法来进行非编组.
我不控制发件人.发件人处于网络字节顺序.我的问题只是: - 将缓冲区强制转换为结构,然后在此类型结构上使用ntohs和ntohl来制作此结构的主机字节顺序副本是否安全?这是最快的方法吗?如果没有,那么最快的方法是什么?
我正在实现一个循环缓冲区来存储固定大小的数据结构,如队列.这个循环缓冲区初始化有三个参数: -
/*
* Initialize the ring buffer.
* @capacity Max capacity of ring buffer.
* @item_size Fixed size of item that will be put in this circular buffer.
* @item_cleaner Clean callback, NULL if cleanup not required.
*/
ringbuf*
ringbuf_create(size_t capacity, size_t item_size, clean_up_cb item_cleaner)
Run Code Online (Sandbox Code Playgroud)
我的循环缓冲区始终处于wrapping模式状态,这意味着当新项目放入完整循环缓冲区时,始终会替换最后一项.因为,动态分配的对象也可以放入此缓冲区,因此,循环缓冲区会保持引用清理回调函数,以便在替换或删除项目时释放它们.但与此同时,这个回调函数也可以NULL(当不需要清理时).在我的代码中的任何地方,我都有这样的陈述: -
if(buffer->callback != NULL)
buffer->callback(item);
Run Code Online (Sandbox Code Playgroud)
现在,为了防止这些if语句,当用户没有提供任何回调函数时,我把空存根函数.这使我无法每次检查是否有回调函数NULL.
使用这种方法,我的代码看起来很整洁.但我不确定,哪一个更快?在装配层面,速度方面如何empty function call和if statement相关?它们是等价的吗?
我正在制作一个与使用大端字节排序的患者监视器通信的C程序.例如,如果我确定C结构
typedef struct {
int short a;
int short b;
int c;
} msg;
Run Code Online (Sandbox Code Playgroud)
要阅读这种结构,我可以简单地使用ntohs(msg.a),ntohs(msg.b),ntohl(msg.c).但是一些结构具有短整数缓冲区,但缓冲区本身是另一种结构的类型.例如,
typedef struct {
int short length;
int short b[MAX_BUF_SIZE];
} msg1;
Run Code Online (Sandbox Code Playgroud)
上述结构中的字段"b"表示另一种结构,如下所示:
typedef struct {
int short a;
int short b;
} msg2;
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是1)我应该将结构"msg1"的所有短整数转换为主机顺序,然后将其转换为"msg2"类型的指针,并简单地读取"msg2.a"和"msg2.b"或2)我应该转换"msg2.a"和"msg2.b"的字节顺序或3)只是将"msg1.b"转换为"msg2"类型的指针并读取"msg2.a"和"msg2.b"通过将每个转换为主机订单?
请告诉我们哪种方法是正确的,以便阅读msg1
int t[msg1.length];
for(int i = 0; i < msg1.length; i++)
t[i] = ntohs(*(msg1.b + i));
msg2 * msg2_m = (msg2 *)t;
/* should I convert the msg2_m.a and msg2_m.b as well? */
printf("%d:%d", msg2_m.a, msg2_m.b);
Run Code Online (Sandbox Code Playgroud)
所有相同的除外
printf("%d:%d", ntohs(msg2_m.a), …Run Code Online (Sandbox Code Playgroud) 我正在使用epoll管理约20到30个套接字。我发现epoll_wait可以用于等待一些数据通过套接字之一到达,但是我错过了如何在套接字级别实现超时。我可以在epoll_wait上使用超时,但是对于我来说不是很有用。例如,如果我需要每次关闭一个套接字,而在该套接字中没有记录任何活动,时间超过500毫秒,那么无论如何,orr可能每200毫秒将一些数据发送到套接字。如何使用epoll实现这些套接字级别的超时?任何建议和想法将不胜感激!
谢谢,Shivam Kalra
我试图理解,为什么GCC f(char, A<C, 5> &var)在下面的代码中选择重载解析:
template <class C, int N> struct A { };
template <class C> struct A<C, 8> { static_assert(sizeof(C) > 8, "Assertion in A<C,8>"); };
template <class C> struct A<C, 5> { static_assert(sizeof(C) < 8, "Assertion in A<C,5>"); operator A<C,8>&(); };
template <class C> void f(double, A<C,8> &var);
template <class C> void f(char, A<C,5> &var);
int main(void)
{
A<int, 5> a;
f(4., a);
}
Run Code Online (Sandbox Code Playgroud)
有两种可用的重载:
template <class C> void f(double, A<C,8> &var);
Run Code Online (Sandbox Code Playgroud)
4.完全匹配double(不需要隐式转换),但第二个参数需要用户定义的转换.所以这个过载: …
我正在编写一个程序,使用无连接(UDP)套接字与某些患者监视器进行通信.我需要一个建议,我应该使用最快,最有效的算法来解析从病人监护仪接收的数据.
病人监护仪将数据作为AttributeList结构发送,结构的定义如下: -
typedef struct {
uint16 count;
uint16 length;
AVAType * values;
} AttributeList;
typdef struct {
uint16 id;
uint16 length;
void * data;
} AVAType
Run Code Online (Sandbox Code Playgroud)
因此,AttributeList包含许多AVAType结构,并且每个AVAType结构都包含id和数据作为void指针(数据只是AVAType中实际数据的占位符).事实上,为AVAType和每个ID定义了大约150个ID,数据必须放在一些相应的数据结构中以便进行解析.
因此,如果AVAType结构中的ID为1,则必须使用算法A解析数据,但如果ID为2则必须使用算法B解析数据,依此类推......
我目前的方法是使用150个if-else语句并加载AVAType的特定数据结构,然后解析结果.患者监护仪也按网络顺序发送数据,我需要根据ID解压缩AVAType.
请提出一些处理这种情况的好方法.这只是一个大学的事情,我不是很安全的兄弟,我认为安全可以逐步改善,但现在我对速度的关注.
是的,它是actaully AVAType值[];.您能否更具体地说明为何与AVAType*不同?如果我以其他方式定义我的结构,它会有用吗?
c ×5
endianness ×3
networking ×2
sockets ×2
algorithm ×1
c++ ×1
c++11 ×1
epoll ×1
events ×1
gcc ×1
performance ×1
standards ×1