Chinaunix首页 | 论坛 | 博客
  • 博客访问: 144142
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-19 19:25
个人简介

迷茫的开发

文章分类

全部博文(43)

文章存档

2022年(1)

2019年(14)

2017年(10)

2016年(18)

我的朋友

分类: C/C++

2017-09-07 09:47:30

    最近在移植项目以前的功能到新项目时,遇到了一个很奇怪的问题:在创建完成端口之后,投递WSARecv的时候,一直返回10014.
  window的错误码官方解释:
//
// MessageId: WSAEFAULT
//
// MessageText:
//
// The system detected an invalid pointer address in attempting to use a pointer argument in a call.
//
#define WSAEFAULT                        10014L

从这个错误码的解释来看,应该是传参错误!首先就是看是否有空指针,再者就是分析逻辑了:
 一般在使用完成端口时,通常都是在服务器端使用:监听端口accept的时候创建一个添加到完成端口中。但是在这里是在客户端使用的完成端口:socket连接是已经建立好的,在某种情况下,如果要大量、长时间的接收数据才考虑使用完成端口接收数据,否则就直接读socket。
    在验证了这些方案的可行性之后,还是回到了最基本的API上,该函数的原型:
int
WSAAPI
WSARecv(
    IN SOCKET s,
    __in_ecount(dwBufferCount) __out_data_source(NETWORK) LPWSABUF lpBuffers,
    IN DWORD dwBufferCount,
    __out_opt LPDWORD lpNumberOfBytesRecvd,
    IN OUT LPDWORD lpFlags,
    __in_opt LPWSAOVERLAPPED lpOverlapped,
    __in_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    );

此时,从网上找了一下其它人的经验,大致分成两种情况:
1.参数传递错误:将lpFlags字段直接传成了0.
    当然我不可能原型都不看就调用,因此排出这种方法。
2.lpBuffers需要4字节对齐
    公司的产品做得比较早,以前为了节约内存都是采用的1字节对齐,因此如果真是有这个限制,那很可能就是这个原因。
而该部分代码使用了一个大型的嵌套结构体,在之前的代码中没有这个问题,而在移植后的代码有这个问题——之前的代码刚刚好是4字节对齐了?


要怎么计算现在到底是不是4字节对齐呢,难道要笔一个一个加,或者是用计算器算?
联想到VS编译器采用的是16进制,而需要的是4字节对齐,那么是否只需要位数是4的倍数就行了?比如对于10进制数,如果位数是5、0则都能被5整除,这只是猜想怎么证明呢?

对于一个16进制整数,如果它只有一位,就是我们要证明的——明显符合。

当其多于一位时,可以表示为k=y*16x+z,其中z为个位,y>=0,x>0,k为该数。从而k=y*16x-1*16+z.故只要能被16整除的数,都可以只看最低位。

比如:对于16机制的数kK能被248整除   等价于    K的最低位能被248整除。

进一步,该结论可以推广到任何进制:

对于K进制的数,如果要判断K能被其某个最大公约数整除,只需要判断其最低位能否被该最大公约数整除比如十进制可以判断的是25
PS:最初我也是拿计算器算的,只是当时有这种想法,回家的路上想到了,早上来做个记录!
                                                                                                                                                                                                                            ——2017.9.7

阅读(1476) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~