我有两个使用CZMQ的独立C程序。一个是客户端,一个是服务器。服务器将数据从文件传输到客户端,客户端将收到的数据写入一个名为" testdata_out的新文件。"一旦客户端从服务器接收到最后一块数据,客户端就会退出。
问题是服务器位于那里,等待向客户端发送更多数据,但客户端程序已完全退出。我已经看过GDB了,服务器只是卡在了
zframe_t *identity = zframe_recv( router );
我使用fprintf()完成了详细的日志记录,以确认是这种情况。
我使用ZMQ File transfer model 3作为我的示例 - 我已经复制了确切的代码并对其进行测试以确保其正常工作。
基本上我正在寻找想法 - 如果身份验证不起作用,我可以将其用作退出条件吗? 我可以以某种方式发送中止信号,因为我无法编辑ZeroMQ功能' zframe_recv?'或者,如果有人能够看到我的代码或设置存在什么问题,那么我可以使用ID验证作为退出条件的修复程序非常棒。
这是服务器功能:
int zmq_send_internal_file( struct arg_struct *args )
{
struct arg_struct *input = (struct arg_struct *)args;
int node_num = input->node;
const char *fp = input->file_name;
int chunkNum = 0;
FILE *file_to_xfer = fopen( fp, "r" );
zctx_t *ctx = zctx_new( );
void *router = zsocket_new (ctx, ZMQ_ROUTER);
//two parts per msg so HWM is size PIPELINE * 2
zsocket_set_hwm (router, PIPELINE * 2);
char *complete_address = "tcp://127.0.0.1:6000";
if( 0 == zsocket_connect (router, complete_address ) )
{
printf("logging here\n");
}
else
{
printf("logging here\n");
}
while (true)
{
//what if we don't check the sender identity as a breaking condition?
//what if we check chunk size as the breaking condition instead? - this causes program to exit too early
//first frame in each message is the sender identity
zframe_t *identity = zframe_recv( router );
if (!identity)
{
printf("no identity, breaking.\n");
break; //if we can't find an id, we're all set
}
//second frame is 'fetch' command
char *command = zstr_recv (router);
assert (streq (command, "fetch"));
free (command);
//third frame is chunk offset in file
char *offset_str = zstr_recv (router);
size_t offset = atoi (offset_str);
free (offset_str);
fprintf( fp_clnt_log, "%s : zmq:frame 4\n", time_str );
//fourth frame is max chunk size
char *chunksz_str = zstr_recv (router);
size_t chunksz = atoi (chunksz_str);
free (chunksz_str);
//read chunk of data from file
fseek (file_to_xfer, offset, SEEK_SET);
byte *data = malloc (chunksz);
assert (data);
//send resulting chunk to client
size_t size = fread (data, 1, chunksz, file_to_xfer);
zframe_t *chunk = zframe_new (data, size);
zframe_send (&identity, router, ZFRAME_MORE);
zframe_send (&chunk, router, 0);
chunkNum++;
}
if ( 0 == fclose( file_to_xfer ) )
{
printf("file_to_xfer closed successfully. \n");
}
else
{
printf("failed to close file_to_xfer. Exiting.\n");
return -1;
}
return 0;
}
这是客户端功能:
void
zmq_receive_file()
{
FILE *fp_out = fopen ("/usr/vos/bin/testdata_out","w");
if ( NULL == fp_out )
{
printf( "fp_out pointer is NULL.\n");
}
return;
}
zctx_t *ctx = zctx_new ();
void *dealer = zsocket_new (ctx, ZMQ_DEALER);
zsocket_bind (dealer, "tcp://*:6000");
//up to PIPELINE number of chunks can be in transit
size_t credit = PIPELINE;
size_t total = 0; //total bytes received
size_t chunks = 0; //total chunks received
size_t offset = 0; //offset of next chunk request
int chunkNum = 0;
while (true)
{
while (credit) //ask for next chunks until credit is 0
{
printf("%s : ft_server has credit, requesting next chunk...\n", time_str);
zstr_sendm (dealer, "fetch");
zstr_sendfm (dealer, "%ld", offset);
chunkNum++;
chunks++;
}
zframe_t *chunk = zframe_recv (dealer);
if( !chunk )
{
break; //shut down and quit
}
//if there IS a chunk, write it to testdata_out
else
{
size_t bytes_in_frame = zframe_size( chunk );
char *data = zframe_data( chunk );
fwrite( data, bytes_in_frame, 1, fp_out );
}
time_str = asctime( timeinfo );
chunks++;
credit++;
size_t size = zframe_size (chunk);
total+=size;
if (size < CHUNK_SIZE)
{
printf ( "%s : Chunk smaller than CHUNK_SIZE, all done.\n");
break; //last chunk received, exit
//program exits and leaves server hanging and waiting for an identity, so it never exits
}
}
fclose( fp_out );
}
答案 0 :(得分:2)
服务器中的读取是阻塞的,即只有在实际收到消息时它才会返回。
以下是一些获取所需行为的选项: