链接protobuf遇到的一个坑,记录下来备忘一下

2 篇文章 0 订阅

[libprotobuf FATAL google/protobuf/generated_message_util.cc:783] CHECK failed: (scc->visit_status.load(std::memory_order_relaxed)) == (SCCInfoBase::kRunning): 

terminate called after throwing an instance of 'google::protobuf::FatalException'
  what():  CHECK failed: (scc->visit_status.load(std::memory_order_relaxed)) == (SCCInfoBase::kRunning): 

 程序使用protobuf,编译没有问题,运行时一到建立protobuf对象就崩溃,搜索了半天没找到原因,后来偶然看到以前正常使用的makefile文件中后面加了-lpthread,加上就好了。我自己的程序没有用到多线程,怀疑是protobuf3里面用到了。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
由于Protobuf只是一种数据序列化格式,它并不包含网络传输的相关功能。因此,如果要使用Protobuf作为TCP协议栈的数据格式,需要借助其他库来完成网络传输的功能。下面是一个使用Java语言和Netty库实现的示例: 1. 定义Protobuf消息 首先,我们需要定义一个或多个Protobuf消息,用于在网络上传输数据。例如,我们可以定义一个名为"Message"的消息,包含一个字符串类型的"content"字段和一个整型类型的"length"字段,用于表示消息内容和长度。定义如下: ``` syntax = "proto3"; message Message { string content = 1; int32 length = 2; } ``` 2. 实现服务器 接下来,我们需要实现一个服务器,用于监听TCP连接并接收和发送Protobuf消息。我们可以使用Netty库来实现这个服务器。以下是一个简单的实现: ``` public class Server { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtobufVarint32FrameDecoder()); pipeline.addLast(new ProtobufDecoder(Message.getDefaultInstance())); pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast(new ProtobufEncoder()); pipeline.addLast(new ServerHandler()); } }); ChannelFuture f = b.bind(8888).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } } ``` 在这个实现中,我们创建了一个ServerBootstrap实例,并设置了bossGroup和workerGroup两个EventLoopGroup。然后,我们指定了NioServerSocketChannel作为服务器的Channel类型,并设置了一个ChannelInitializer,用于初始化接收到的连接的ChannelPipeline。 在ChannelPipeline中,我们添加了几个处理器,用于完成Protobuf消息的编解码和处理。其中,ProtobufVarint32FrameDecoder和ProtobufDecoder用于解码接收到的数据,ProtobufVarint32LengthFieldPrepender和ProtobufEncoder用于编码发送的数据。ServerHandler则是我们自己实现的消息处理器,用于处理接收到的Protobuf消息。 3. 实现消息处理器 最后,我们需要实现一个消息处理器,用于处理接收到的Protobuf消息。以下是一个简单的实现,用于将接收到的消息内容转换为大写形式,并返回给客户端: ``` public class ServerHandler extends SimpleChannelInboundHandler<Message> { @Override public void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception { String content = msg.getContent().toUpperCase(); int length = content.length(); Message response = Message.newBuilder() .setContent(content) .setLength(length) .build(); ctx.writeAndFlush(response); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } } ``` 在这个实现中,我们继承了SimpleChannelInboundHandler,该类可以帮助我们自动释放接收到的消息,从而避免内存泄漏问题。在channelRead0方法中,我们将接收到的消息内容转换为大写形式,并计算消息长度,然后构造一个新的Protobuf消息作为响应,最后通过ctx.writeAndFlush方法将响应发送给客户端。 这样,我们就实现了一个简单的使用Protobuf作为数据格式的TCP协议栈。当客户端连接到服务器,并发送一个包含"hello, world"字符串的消息时,服务器会将其转换为"HELLO, WORLD"字符串,并返回给客户端。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值