{
buffer_free,
staticintsock_write(BIO*b,constchar*in,intin
unsignedlongnum_read;//读出的数据长度
return(ret);
{
buffer_write,
if(i<=0)
if(ret<=0)
if(i>0)/*letsfillitupifwecan*/
if(BIO_sock_should_retry(ret))
if(ctx->obuf_len!=0)//加入当前的数据后刷新缓冲区
structbio_st*next_bio;
BIO提供了BIO_ctrl接口函数,使用这个函数可以对BIO进行控制,类似于标准文件操作的ioctl,类似于关联BIO和文件描述符的操作都是使用这个接口函数完成的,很多的操作都会定位到这个BIO_ctrl函数,对于不同的BIO类型,其ctrl也不同,其实ctrl函数也是通达信 python语言接口,回调函数集合中的一个,BIO_ctrl最终会调用BIO类型特定的ctrl通达信 python语言接口,回调函数的。
...//不考虑的情况
intinit;//是否已经初始化标志
intret;
unsignedlongnum_write;//写入的数据长度
}
{
...//偏移处理
for(;;)//循环刷新,直到终了或者出错
BIO机制提供BIO_write接口函数,该接口函数的实现就是调用不同BIO的通达信 python语言接口,回调函数集合中的write函数,对于这些通达信 python语言接口,回调函数怎么实现就看用户的策略了,BIO仅仅是提供了一个总体的框架,它对内部的实现没有任何要求,正如上面说的,控制权也被集成在了通达信 python语言接口,回调函数里面,比如一个过滤类型的BIO的write通达信 python语言接口,回调函数的实现中就有BIO_write(b->next_bio,...)接口函数的调用,再比如对于源/目的类型的BIO,一个connect的socket的write通达信 python语言接口,回调函数就是:
{
}
return(&methods_buffer);
void*ptr;//私有数据指针,对于不同的BIO类型有着不同的解释,比如对于一个加密解密的BIO,它就是一个BIO_ENC_CTX
}
intshutdown;//BIO是否已经打开
char*cb_arg;//通达信 python语言接口,回调函数的参数
...//结束或者出错处理以及偏移处理
staticBIO_METHODmethods_buffer=
long(*callbac(structbio_st*,int,constchar*,int,long,lon;//一个可选的通达信 python语言接口,回调函数,用户可以更好的进行控制
}
};
ret=writesocket(b->num,in,in;
buffer_ctrl,
};
if(i>=in//缓冲区不满的情况下,就将数据加入缓冲区之后然后返回,只有在缓冲区满了或者手动刷新的时候才刷新缓冲区
}
buffer_gets,
仍然以buffer-BIO为例,methods_buffer就是它的重要的通达信 python语言接口,回调函数集合:
{
CRYPTO_EX_DATAex_data;
if((ctx==NUL||(b->next_bio==NUL)return(0);
ctx=(BIO_F_BUFFER_CTX*)b->ptr;
BIO_TYPE_BUFFER,
}
ctx->obuf_len+=i;
BIO_METHOD*BIO_f_buffer(voi
{//调用BIO_write接口函数,注意传入的BIO是当前BIO链的下一个BIO,数据就是缓冲区内的数据
intreferences;
{
memcpy(&(ctx->obuf[ctx->obuf_len]),in,in;
i=BIO_write(b->next_bio,&(ctx->obuf[ctx->obuf_off]),ctx->obuf_le;
structbio_st*prev_bio;
BIO_clear_retry_flags(;
buffer_puts,
{
staticintbuffer_write(BIO*b,constchar*in,intin
intnum;
{
ctx->obuf_len+=inl;
以上是buffer类型的BIO的一个write通达信 python语言接口,回调函数,buffer类型的BIO是一种很简单的过滤类型的BIO,仅仅提供两个缓冲区用于缓冲数据,别的什么也不做,在buffer-BIO的上层,用户调用BIO_write写入数据,写到哪里了呢?事实上是缓存到buffer的输出缓冲区里面了,等到缓冲区满了的时候再将其刷入更底层的BIO,这个更底层的BIO可能仍然是一个过滤类型的BIO,也可能是一个源/目的类型的BIO,但是BIO链的最终肯定是一个源/目的类型的BIO而不能是一个过滤类型的BIO或者是NUILL,因此在此通达信 python语言接口,回调函数的最后刷新缓冲区的时候还是用了BIO_write接口函数进行数据写入,最终肯定是写入了一个源/目的类型的BIO代表的数据载体,比如套接字,文件,甚至内存。
return(num+in;
buffer_read,
inti,num=0;
更为复杂的加密解密BIO复杂在处理细节,处理逻辑和上面的buffer-BIO是一样的,只不过在写入下层的BIO之前将数据加密了,在读取的时候,从下层BIO读到数据之后先解密然后再传递给更为上层的BIO。在openssl中,控制逻辑十分简单,BIO_write接口函数可以被一切可以控制BIO的实体使用,比如最终的用户或者BIO本身,因为BIO是链式的结构,因此整个过程在函数上体现了一个递归的过程,自己控制自己,于这个过程不同的是有些程序的逻辑大量使用了MVC架构,其中抽象出一个控制器,这种方式固然不错,但是我个人感觉openssl的方式看起来更加美丽。有的时候这种递归的控制方式十分有效,它的特点在于将控制器集成到了通达信 python语言接口,回调函数本身,你难道在深感此方式难懂的同时不觉得它也很灵活吗?
structbio_st
intretry_reason;
{
buffer_new,
BIO_METHOD*method;//BIO方法结构,是决定BIO类型和行为的重要参数,各种BIO的不同之处主要也正在于此项。
start:
clear_socket_error();
i=ctx->obuf_size-(ctx->obuf_len+ctx->obuf_of;
BIO_clear_retry_flags(;
BIO的架构很简单,基本就是一个结构体和一个通达信 python语言接口,回调函数集合:
if((in==NUL||(inl<=0))return(0);
BIO_set_retry_write(;
}
BIO_F_BUFFER_CTX*ctx;
intflags;
'buffer',
buffer_callback_ctrl,
memcpy(&(ctx->obuf[ctx->obuf_len]),in,;
文章为作者独立观点,不代表股票交易接口观点