bitfield在内存卡0字节修复中占多少字节

1730人阅读
入门(25)
写出下列程序在X86上的运行结果。 struct mybitfields { unsigned short a : 4; unsigned short b : 5; unsigned short c : 7; } void main(void)
{ test.a=2; test.b=3; test.c=0; i=*((short *)&test); printf("%d ",i); }
这个题的为难之处呢,就在于前面定义结构体里面用到的冒号,如果你能理解这个符号的含义,那么问题就很好解决了。这里的冒号相当于分配几位空间,也即在定义结构体的时候,分配的成员a 4位的空间, b 5位,c 7位,一共是16位,正好两个字节。下面画一个简单的示意:变量名
15 14 13 12 11 10 9 |8 7 6 5 4 |3 2 1 0 test.a
|0 0 1 0 test.b
|0 0 0 1 1 |test.c
|在执行i=*((short *)&test); 时,取从地址&test开始两个字节(short占两个字节)的内容转化为short型数据,即为0x0032,再转为int型为0x,即50。输出的结果就是50。当然,这里还涉及到字节及位的存储顺序问题,后面再说。
前面定义的结构体被称为位结构体。所谓位结构体,是一种特殊的结构体,在需要按位访问字节或字的一个或多个位时,位结构体比按位操作要更方便一些。位结构体的定义方式如下:struct [位结构体名]{数据类型 变量名:整数常数;...}位结构变量;说明:1)这里的数据类型只能为int型(包括signed和unsigned); 2)整数常数必须为0~15之间的整数,当该常数为1时,数据类型为unsigned(显然嘛,只有一位,咋表示signed?光一符号?没意义呀); 3)按数据类型变量名:整数常数;方式定义的结构成员称为位结构成员,好像也叫位域,在一个位结构体中,可以同时包含位结构成员及普通的结构成员; 4)位结构成员不能是指针或数据,但结构变量可以是指针或数据; 5)位结构体所占用的位数由各个位结构成员的位数总各决定。如在前面定义的结构体中,一共占用4+5+7=16位,两个字节。另外我们看到,在定义位结构成员时,必须指定数据类型,这个数据类型在位结构体占用多少内存时也起到不少的作用。举个例子:struct mybitfieldA{char a:4;char b:3;}testA; struct mybitfieldB{short a:4;short b:3;}testB; 这里,testA占用一个字节,而testB占用两个字节。知道原因了吧。在testA中,是以char来定义位域的,char是一个字节的,因此,位域占用的单位也按字节做单位,也即,如果不满一个字节的话按一个字节算(未定义的位按零处理)。而在testB中,short为两个字节,所以了,不满两个字节的都按两个字节算(未定义位按零处理) 关于位结构体在内存中的存储问题Kevin's Theory #2: In a C structure that contains bit fields, if field A is defined in front of field B, then field A always occupies a lower bit address than field B. (来自http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxk&Number=638637&page=0&view=collapsed&sb=5&o=all&fpart=all) 说的是,在C结构体中,如果一个位域A在另一个位域B之前定义,那么位域A将存储在比B小的位地址中。 如果一个位域有多个位时,各个位的排列顺序通常是按CPU的端模式(Endianess)来进行的,即在大端模式(big endian)下,高有效位在低位地址,小端模式则相反。补充说明一个关于位域与普通结构成员一起使用的问题先看一个例子struct mybitfield{char a:4;char b:3;char c:1;} 这种情况下,test应该占几个字节呢?2个(4+3+1=8占一个字节,aa占一个)还是3个(4+3不足补一位,占一个字节,aa占一个字节,c占一个字节)?写个小程序验证一下:int main(int argc, char* argv[]) {
test.a = 1;
test.b = 1;
test.aa = 1;
test.c = 1; i=*((short *)&test);
printf("%d /n",i); return 0; } 输出结果是273,化为十六进制数0x111,可见是按三个字节来处理了(如果按两个字节处理的话,cba组成一个字节,是(十六进制0x91)再加上aa,那就应该是0x191了) 举这个例子是为了说明一下,定义位域的话,最好是把所以有位域放在一起,这样可以节省空间(如果把c和aa换一下位置,那test就只占两个字节了)。另外也是为了强调一下位结构体的内存分配方式,按定义的先后顺序来分配,而位域(或成员)内的字节顺序则按照CPU的位顺序来进行(一般与CPU的端模式对应)。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:228503次
积分:1463
积分:1463
排名:千里之外
原创:11篇
转载:30篇
评论:57条
专注JAVA C/C++android
(1)(1)(5)(2)(1)(25)(1)(3)(2)写出下列程序在X86上的运行结果。struct mybitfields{unsigned short a : 4;unsigned short b : 5;unsigned short c : 7;}
void main(void)&{test.a=2;test.b=3;test.c=0;i=*((short *)&test);printf("%d ",i);}
这个题的为难之处呢,就在于前面定义结构体里面用到的冒号,如果你能理解这个符号的含义,那么问题就很好解决了。这里的冒号相当于分配几位空间,也即在定义结构体的时候,分配的成员a 4位的空间, b 5位,c 7位,一共是16位,正好两个字节。下面画一个简单的示意:
变量名&&位数
test&&&&15 14 13 12 11 10 9 |8 7 6 5 4 |3 2 1 0
test.a&&&&&&&&&&&&&&&&&&&&&&|&&&&&&&&&&|0 0&1 0
test.b&&&&&&&&&&&&&&&&&&&&&&|0 0 0 1 1 |
test.c&&&0&&0&&0&&0&&0&&0 0 |&&&&&&&&&&|
在执行i=*((short *)&test); 时,取从地址&test开始两个字节(short占两个字节)的内容转化为short型数据,即为0x0032,再转为int型为0x,即50。输出的结果就是50。当然,这里还涉及到字节及位的存储顺序问题,后面再说。
前面定义的结构体被称为位结构体。所谓位结构体,是一种特殊的结构体,在需要按位访问字节或字的一个或多个位时,位结构体比按位操作要更方便一些。
位结构体的定义方式如下:
struct [位结构体名]{
数据类型 变量名:整数常数;
}位结构变量;
1)这里的数据类型只能为int型(包括signed和unsigned);
2)整数常数必须为0~15之间的整数,当该常数为1时,数据类型为unsigned(显然嘛,只有一位,咋表示signed?光一符号?没意义呀);
3)按数据类型变量名:整数常数;方式定义的结构成员称为位结构成员,好像也叫位域,在一个位结构体中,可以同时包含位结构成员及普通的结构成员;
4)位结构成员不能是指针或数据,但结构变量可以是指针或数据;
5)位结构体所占用的位数由各个位结构成员的位数总各决定。如在前面定义的结构体中,一共占用4+5+7=16位,两个字节。另外我们看到,在定义位结构成员时,必须指定数据类型,这个数据类型在位结构体占用多少内存时也起到不少的作用。举个例子:
struct mybitfieldA{
struct mybitfieldB{
short&a:4;
short&b:3;
这里,testA占用一个字节,而testB占用两个字节。知道原因了吧。在testA中,是以char来定义位域的,char是一个字节的,因此,位域占用的单位也按字节做单位,也即,如果不满一个字节的话按一个字节算(未定义的位按零处理)。而在testB中,short为两个字节,所以了,不满两个字节的都按两个字节算(未定义位按零处理)
关于位结构体在内存中的存储问题
Kevin's Theory #2: In a C structure that contains bit fields, if field A is defined in front of field B, then field A always occupies a lower bit address than field B. (来自)
说的是,在C结构体中,如果一个位域A在另一个位域B之前定义,那么位域A将存储在比B小的位地址中。
如果一个位域有多个位时,各个位的排列顺序通常是按CPU的端模式(Endianess)来进行的,即在大端模式(big endian)下,高有效位在低位地址,小端模式则相反。
补充说明一个关于位域与普通结构成员一起使用的问题
先看一个例子
struct mybitfield{
char c:1;}
这种情况下,test应该占几个字节呢?2个(4+3+1=8占一个字节,aa占一个)还是3个(4+3不足补一位,占一个字节,aa占一个字节,c占一个字节)?
写个小程序验证一下:
int main(int argc, char* argv[]){&&test.a = 1;&test.b = 1;&test.aa = 1;&test.c = 1;
&i=*((short *)&test);&printf("%d /n",i);
&return 0;}
输出结果是273,化为十六进制数0x111,可见是按三个字节来处理了(如果按两个字节处理的话,cba组成一个字节,是(十六进制0x91)再加上aa,那就应该是0x191了)
举这个例子是为了说明一下,定义位域的话,最好是把所以有位域放在一起,这样可以节省空间(如果把c和aa换一下位置,那test就只占两个字节了)。另外也是为了强调一下位结构体的内存分配方式,按定义的先后顺序来分配,而位域(或成员)内的字节顺序则按照CPU的位顺序来进行(一般与CPU的端模式对应)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:20971次
排名:千里之外
原创:11篇
(1)(1)(1)(2)(8)(3)BitTorrent协议分析四
位图管理模块的设计和实现
bitfield.hbitfield.c
bitfield.h
#ifndef BITFIELD_H
#define BITFIELD_H
typedef struct _Bitmap {
unsigned char&
int&&&&&&&&&&
bitfield_ //
位图所占的总字节数
int&&&&&&&&&&
位图有效的总位数,每一位代表一个piece
create_bitfield();&&&&&&&&&&&&&&&&&&&&&
创建位图,分配内存并进行初始化
int& get_bit_value(Bitmap
*bitmap,int index);&&&
获取某一位的值
int& set_bit_value(Bitmap
*bitmap,int index, unsigned char value);
设置某一位的值
int& all_zero(Bitmap
*bitmap); &&&&&&&&&&&&&&&&&
int& all_set(Bitmap
*bitmap);&&&&&&&&&&&&&&&
全部设置为1
release_memory_in_bitfield();&&&&&&&&&&
释放bitfield.c中动态分配的内存
int& print_bitfield(Bitmap
*bitmap);&&&&&&&&
打印位图值,用于调试
int& restore_bitmap();
将位图存储到文件中
&&&&&&&&&&&&&&&&
在下次下载时,先读取该文件获取已经下载的进度
int& is_interested(Bitmap
*dst,Bitmap *src);& &&
拥有位图src的peer是否对拥有
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&
// dst位图的peer感兴趣
get_download_piece_num(); &&&&&
&&&&&&&&&&&&
获取当前已下载到的总piece数
1Bitmapbitfield_lengthbitfieldvalid_length1007955(100
2is_interestedpeerpeer1piecepeer2peer2peer1peer1piece
3get_download_piece_numpieceBitmapbitfield1
bitfield.c
bitfield.c文件头部包括的内容
&unistd.h&
&string.h&
&malloc.h&
&sys/types.h&
&sys/stat.h&
#include "parse_metafile.h"
#include "bitfield.h"
extern int&
extern char *file_
Bitmap&&&&
& *bitmap =
NULL;&&&&&&&
int&&&&&&&&
download_piece_num = 0; //
当前已下载的piece数
1extern int pieces_parse_metafile.cextern
2bitmappeerPeer
create_bitfield()
该函数较为简单,不另加注释
create_bitfield()
bitmap = (Bitmap *)malloc(sizeof(Bitmap));
if(bitmap == NULL) {
printf("allocate memory for bitmap fiailed\n");
return -1;
// pieces_length除以20即为总的piece数
bitmap-&valid_length = pieces_length /
bitmap-&bitfield_length = pieces_length / 20 /
if( (pieces_length/20) % 8 != 0 )&
bitmap-&bitfield_length++;
bitmap-&bitfield = (unsigned char
*)malloc(bitmap-&bitfield_length);
if(bitmap-&bitfield == NULL)& {
printf("allocate memory for bitmap-&bitfield
fiailed\n");
if(bitmap != NULL)&
free(bitmap);
return -1;
char bitmapfile[64];
sprintf(bitmapfile,"�itmap",pieces_length);
FILE *fp = fopen(bitmapfile,"rb");
if(fp == NULL) {& //
若打开文件失败,说明开始的是一个全新的下载
memset(bitmap-&bitfield, 0,
bitmap-&bitfield_length);
fseek(fp,0,SEEK_SET);
for(i = 0; i &
bitmap-&bitfield_ i++)
&&&&&&&&&&&&&&
(bitmap-&bitfield)[i] = fgetc(fp);
fclose(fp);
给download_piece_num赋新的初值
download_piece_num = get_download_piece_num();
int get_bit_value(Bitmap
*bitmap,int index)
get_bit_value(Bitmap *bitmap,int index)&
int&&&&&&&&&&
int&&&&&&&&&&
&&&&&byte_
unsigned char &&&&&byte_
unsigned char &&&&&inner_byte_
if(bitmap==NULL || index &=
bitmap-&valid_length)& return -1;
byte_index = index / 8;
byte_value =
bitmap-&bitfield[byte_index];
inner_byte_index = index % 8;
byte_value = byte_value && (7 -
inner_byte_index);
if(byte_value % 2 == 0) ret = 0;
else ret = 1;
get-bit-value2(10100)1414pieceindex07pieceindex813pieceindex8piece
int set_bit_value(Bitmap
*bitmap,int index,unsigned char value)
set_bit_value(Bitmap *bitmap,int index,unsigned char v)
unsigned charinner_byte_
if(bitmapv==NULL || index &=
bitmap-&valid_length)& return -1;
if((v != 0) && (v !=
return -1;
& &&&byte_index
= index / 8;
inner_byte_index = index % 8;
v = v && (7 -
inner_byte_index);
bitmap-&bitfield[byte_index] =
bitmap-&bitfield[byte_index] |
int all_zero(Bitmap
位图所有位清0
all_zero(Bitmap *bitmap)
if(bitmap-&bitfield == NULL)& return -1;
memset(bitmap-&bitfield,0,bitmap-&bitfield_length);
int all_set(Bitmap
all_set(Bitmap *bitmap)
if(bitmap-&bitfield == NULL)& return -1;
memset(bitmap-&bitfield,0xff,bitmap-&bitfield_length);
return 0;&&
release_memory_in_bitfield()
申请的动态内存
release_memory_in_bitfield()
if(bitmap-&bitfield != NULL)
free(bitmap-&bitfield);
if(bitmap != NULL)&
free(bitmap);
& int print_bitfield(Bitmap *bitmap)
用于调试程序
print_bitfield(Bitmap *bitmap)
for(i = 0; i &
bitmap-&bitfield_ i++) {
printf("%.2X ",bitmap-&bitfield[i]); //
以16进制的方式打印每个位图中的字节
if( (i+1) % 16 == 0)&
printf("\n");& //
每行打印16个字节
printf("\n");
int restore_bitmap()
restore_bitmap()
char bitmapfile[64];
if( (bitmap == NULL) || (file_name == NULL) )& return -1;
sprintf(bitmapfile,"�itmap",pieces_length);
fd = open(bitmapfile,O_RDWR|O_CREAT|O_TRUNC,0666);
if(fd & 0)& return -1;
write(fd,bitmap-&bitfield,bitmap-&bitfield_length);
close(fd);
int is_interested(Bitmap
*dst,Bitmap *src)
srcpeer具有dstpeer
is_interested(Bitmap *dst,Bitmap *src)
unsigned char const_char[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char c1, c2;
int&&&&&&&&
if( dst==NULL || src==NULL )& return -1;
if( dst-&bitfield==NULL ||
src-&bitfield==NULL )& return -1;
dst-&bitfield_length!=src-&bitfield_length
|| dst-&valid_length!=src-&
valid_length )
return -1;
如果dst中某位为1而src对应为0,则说明src对dst感兴趣
for(i = 0; i &
dst-&bitfield_length-1; i++) {
for(j = 0; j & 8; j++) {& //
比较某个字节的所有位
&&&&&&&&&&&&&&
c1 = (dst-&bitfield)[i] &
const_char[j];& //
获取每一位的值
&&&&&&&&&&&&&&
c2 = (src-&bitfield)[i] &
const_char[j];
&&&&&&&&&&&&&&
if(c1&0 && c2==0)
j = dst-&valid_length % 8;
dst-&bitfield[dst-&bitfield_length-1];
src-&bitfield[src-&bitfield_length-1];
for(i = 0; i & i++) {& //
比较位图的最后一个字节
if( (c1&const_char[i])&0
(c2&const_char[i])==0 )
&&&&&&&&&&&&&&
测试时可以交换map1.bitfield和map2.bitfield的值或赋于其他值
Bitmap map1, map2;
unsigned char bf1[2] = { 0xa0, 0xa0
位图每一位的值为
unsigned char bf2[2] = { 0xe0, 0xe0
位图每一位的值为
map1.bitfield&&&&&&&
map1.bitfield_length &= 2;
map1.valid_length&&&
map2.bitfield&&&&&&&
map2.bitfield_length& = 2;
map2.valid_length&&&
is_interested(&map1,&map2);&&
printf("%d\n",ret);
get_download_piece_num()
get_download_piece_num()
unsigned char const_char[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
int&&&&&&&&&&
if(bitmap==NULL ||
bitmap-&bitfield==NULL)& return 0;
download_piece_num = 0;
for(i = 0; i &
bitmap-&bitfield_length-1; i++) {
for(j = 0; j & 8; j++) {
&&&&&&&&&&&&&&
if( ((bitmap-&bitfield)[i] &
const_char[j]) != 0)
&&&&&&&&&&&&&&&&&&&
download_piece_num++;
unsigned char c = (bitmap-&bitfield)[i];& //
c存放位图最后一个字节的值
j = bitmap-&valid_length % 8;&&&&&&&&
// j是位图最后一个字节的有效位数
for(i = 0; i & i++) {
if( (c & const_char[i]) !=0 )
download_piece_num++;
return download_piece_
出错处理模块的设计和实现
bterror.hbterror.c
#ifndef BTERROR_H
#define BTERROR_H
#define FILE_FD_ERR&&&&&&&&
&&&&&&&&&&&
无效的文件描述符
#define FILE_READ_ERR&&&&&&&&&&
读文件失败
#define FILE_WRITE_ERR&&&&&&&&&
写文件失败
#define INVALID_METAFILE_ERR&&&&&&&
无效的种子文件
#define INVALID_SOCKET_ERR&&&&&
无效的套接字
INVALID_TRACKER_URL_ERR&&&&
无效的Tracker
INVALID_TRACKER_REPLY_ERR&&
无效的Tracker回应
#define INVALID_HASH_ERR&&&&&&&
无效的hash值
#define INVALID_MESSAGE_ERR&&&&
无效的消息
#define INVALID_PARAMETER_ERR&&&&&&
无效的函数参数
FAILED_ALLOCATE_MEM_ERR&&&&
申请动态内存失败
#define NO_BUFFER_ERR&&&&&&&&&&
没有足够的缓冲区
#define READ_SOCKET_ERR&&&&&&&&
读套接字失败
#define WRITE_SOCKET_ERR&&&&&&&
写套接字失败
#define RECEIVE_EXIT_SIGNAL_ERR
接收到退出程序的信号
用于提示致命性的错误,程序将终止
void btexit(int errno,char *file,int
&unistd.h&
&stdlib.h&
#include "bterror.h"
void btexit(i nt errno,char *file,int
printf("exit at %s : %d with error number : %d\n",file, line,
exit(errno);
运行日志模块的设计和实现
log.hlog.c
#ifndef& LOG_H
#define& LOG_H
&stdarg.h&
用于记录程序的行为
void logcmd(char *fmt,...);
打开日志文件
int init_logfile(char
*filename);
将程序运行日志记录到文件
int logfile(char *file,int line,char
&unistd.h&
&stdlib.h&
&string.h&
&sys/stat.h&
&sys/types.h&
#include "log.h"
日志文件的描述符
int logfile_fd = -1;
在命令行上打印一条日志
void logcmd(char *fmt,...)
va_start(ap,fmt);
vprintf(fmt,ap);
va_end(ap);
打开记录日志的文件
int init_logfile(char
*filename)
logfile_fd =
open(filename,O_RDWR|O_CREAT|O_APPEND,0666);
if(logfile_fd & 0) {
printf("open logfile failed\n");
return -1;
将一条日志写入日志文件
int logfile(char *file,int line,char
char buff[256];
if(logfile_fd & 0)& return -1;
snprintf(buff,256,"%s:%d %s\n",file,line,msg);
write(logfile_fd,buff,strlen(buff));
logcmdprintflogcmd(%s:%d error\n,__FILE__, __LINE__);printf(%s:%d error\n,__FILE__, __LINE__);
信号处理模块的设计和实现
SIGINTSIGTERMsignal_hander.hsignal_hander.c
signal_hander.h
#ifndef SIGNAL_HANDER_H
SIGNAL_HANDER_H
做一些清理工作,如释放动态分配的内存
do_clear_work();
处理一些信号
process_signal(int signo);
设置信号处理函数
set_signal_hander();
signal_hander.c
signal_hander.c
&unistd.h&
&stdlib.h&
&signal.h&
#include "parse_metafile.h"
#include "bitfield.h"
#include "peer.h"
#include "data.h"
#include "tracker.h"
#include "torrent.h"
#include "signal_hander.h"
extern int&
download_piece_
extern int& *
extern int& fds_
extern Peer *peer_
程序将退出时,执行一些清理工作
void do_clear_work()
关闭所有peer的socket
Peer *p = peer_
while(p != NULL) {
if(p-&state != CLOSING)&
close(p-&socket);
if(download_piece_num & 0) {
restore_bitmap();
关闭文件描述符
for(i = 0; i & fds_ i++) {
close(fds[i]);
释放动态分配的内存
release_memory_in_parse_metafile();
release_memory_in_bitfield();
release_memory_in_btcache();
release_memory_in_peer();
release_memory_in_torrent();
void process_signal(int signo)
printf("Please wait for clear operations\n");
do_clear_work();
设置信号处理函数
int set_signal_hander()
if(signal(SIGPIPE,SIG_IGN) == SIG_ERR) {
perror("can not catch signal:sigpipe\n");
return -1;
if(signal(SIGINT,process_signal) == SIG_ERR) {
perror("can not catch signal:sigint\n");
return -1;
if(signal(SIGTERM,process_signal) == SIG_ERR) {
perror("can not catch signal:sigterm\n");
return -1;
Peer管理模块的设计和实现
TCPPeerPeerPeerPeerPeerPeerPeer
#ifndef PEER_H
#define PEER_H
&string.h&
#include "bitfield.h"
#define& INITIAL&&&&&&&&
表明处于初始化状态
HALFSHAKED&&&&
表明处于半握手状态
HANDSHAKED&&&&
表明处于全握手状态
SENDBITFIELD&&&
表明处于已发送位图状态
RECVBITFIELD&&&
表明处于已接收位图状态
#define& DATA&&&&&&&&&&&&&
表明处于与peer交换数据的状态
#define& CLOSING&&&&&&&&&
表明处于即将与peer断开的状态
发送和接收缓冲区的大小,16K可以存放一个slice,2K用来存放其他消息
#define& MSG_SIZE&
typedef struct
_Request_piece {
&&&&&&&&&&&&&&
请求的piece的索引
&&&&&&&&&&&&&&
请求的piece的偏移
&&&&&&&&&&&&&
请求的长度,一般为16KB
struct _Request_piece *
Request_& //
定义数据请求队列的结点
int&&&&&&&&&&&
&&&&&&&&&&&&&&
通过该socket与peer进行通信
char&&&&&&&&&&
ip[16];&&&&&&&&&&&&&&
peer的ip地址
unsigned short&&
&&&&&&&&&&&&&&&
// peer的端口号
char&&&&&&&&&&
id[21];&&&&&&&&&&&&&&
int&&&&&&&&&&&
&&&&&&&&&&&&&&&&
当前所处的状态
int&&&&&&&&&&&
am_&&&&&&&&&
是否将peer阻塞
int&&&&&&&&&&&
am_&&&&&&&&
是否对peer感兴趣
int&&&&&&&&&&&
peer_&&&&&&&&&
是否被peer阻塞
int&&&&&&&&&&&
是否被peer感兴趣
Bitmap&&&&&&&&
&&&&&&&&&&&&&&
存放peer的位图
char&&&&&&&&&
*in_&&&&&&&&&&&&
存放从peer处获取的消息
int&&&&&&&&&&&
buff_&&&&&&&&&&&&
缓存区in_buff的长度
char&&&&&&&&&
*out_&&&&&&&&&&&&
存放将发送给peer的消息
int&&&&&&&&&&&
msg_&&&&&&&&&&&&&
缓冲区out_msg的长度
char&&&&&&&&&
*out_msg_&&&&&
out_msg的副本,发送时使用该缓冲区
int&&&&&&&&&&&
msg_copy_&&&&&&&&
缓冲区out_msg_copy的长度
int&&&&&&&&&&&
msg_copy_&&&&&
下一次要发送的数据的偏移量
Request_piece&
*Request_piece_&&
向peer请求数据的队列
Request_piece&
*Requested_piece_ &&
被peer请求数据的队列
unsigned int&&&
down_&&&&&&&&&&
从该peer下载的总字节数
unsigned int&&&
up_&&&&&&&&&&&&&
向该peer上传的总字节数
time_t&&&&&&&&
start_&&&&&&
最近一次接收到peer消息的时间
time_t&&&&&&&&
recet_&&&&&
最近一次发送消息给peer的时间
time_t&&&&&&&&
last_down_&&
最近下载数据的开始时间
time_t&&&&&&&&
last_up_&&&&
最近上传数据的开始时间
long long&&&&&
down_&&&&&&
本计时周期从peer下载的数据的字节数
long long&&&&&
本计时周期向peer上传的数据的字节数
float&&&&&&&&&
down_&&&&&&&&
本计时周期从peer处下载数据的速度
float&&&&&&&&&
up_&&&&&&&&&&
本计时周期向peer处上传数据的速度
struct _Peer&&
initialize_peer(Peer *peer);&&&&&&
对peer各个成员进行初始化
Peer* add_peer_node();&&&&&&&&&&&&&&&
添加一个peer结点
del_peer_node(Peer *peer);&&&&&&&
删除一个peer结点
void& free_peer_node(Peer
*node);&&&&&&
释放一个peer结点的内存
cancel_request_list(Peer *node);&&&
撤消当前请求队列
cancel_requested_list(Peer *node);& &&
撤消当前被请求队列
release_memory_in_peer();&&&&&&
释放peer.c中的动态分配的内存
print_peers_data();&&&&&&&&&&&&&
打印peer链表中某些成员的值,用于调试
图13-3& 状态转换图
1Peerpeer.h713-3
HalfshakedDataPeeram_chokingam_interestedpeer_chokingpeer_interested4
13-4am_interested = 1peer_choking = 0peerpeerrequestpeerpeerpiecepiece
13-5peer_interested = 1am_choking = 0peerpeerpeerrequestpiecepiece
13-5unchokepeerpeerpeerpeerpeerchoke
图13-4& 从下载数据的角度看到的处于Data状态时的内部状态
图13-5& 从上传数据的角度看到的处于Data状态时的内部状态
havepeerpiecepiecehavepeerpiecepeerpiecepeerhavepeer
2Peerout_msgout_msg_copyout_msgsendpeerout_msg_copyout_msg_copy18KBsend1500msg_copy_indexsend1500
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 分配字节内存失败 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信