c:不完整读入int

时间:2015-08-26 16:02:11

标签: c sockets libc

我有一个程序,它分配一个32位的int,然后尝试使用read(2)从套接字读取4个字节到int中

有时读取不完整,返回读取2个字节。有没有办法从中恢复?我想我必须在int的中途生成一个指针才能执行另一次读取。

你应该怎么处理这种情况?我可以想象一些丑陋的方式,但没有优雅的方式。

3 个答案:

答案 0 :(得分:3)

首先需要确保读取4个字节。您可以使用类似于this的功能(略微修改)来执行此操作:

#include <sys/types.h>
#include <sys/socket.h>

int readall(int s, char *buf, int *len)
{
    int total = 0;        // how many bytes we've read
    int bytesleft = *len; // how many we have left to read
    int n = -1;

    while(total < *len) {
        n = read(s, buf+total, bytesleft, 0);
        if (n <= 0)  { break; }  
        total += n;
        bytesleft -= n;
    }

    *len = total; // return number actually read here

    return (n<=0)?-1:0; // return -1 on failure, 0 on success
} 

然后你可以用这四个字节组装一个整数。

答案 1 :(得分:0)

免责声明:这是错误的代码。不要这样做。

int value = 0;
int bytes = 0;
while ( (bytes += read(((char*)&value)+bytes, 4-bytes)) < 4 );

答案 2 :(得分:0)

因此,根据此处和What's the correct way to add 1 byte to a pointer in C/C++?的信息,我得出结论:

  1. 对int进行寻址会导致某些体系结构出现对齐问题。
  2. 您可以尝试通过使用类型惩罚(intchar[]之间的联合)来避免这种情况,但实际上这种技术似乎不比1更可靠。
  3. 进行字节指针运算的唯一真正可移植的方法是将char *用于char[]。因此,处理这种情况的正确方法是将所有字节读入数组并在之后构造int。
  4. 重建为int可以通过ntohl或位移来完成。自it is defined in terms of multiplication以来,Bitshifting可在主机端字节之间移植。
  5. 那么,我们离开了哪里?好吧,便携式选项是读入char[]并使用bitshifting或ntohl进行重建。不可移植的方法是将char *指向你的int,如@ Patrick87建议的那样。

    我走在务实的道路上,刚刚在我的int中创建了一个char*。在我的目标平台上工作得很好。