我使用google协议缓冲区编写了一个c ++代码,但是在运行它时显示错误“未在此范围内声明”,几乎在每一行。我还包含了所需的标题,我想我错过了其中一个步骤,请帮忙。这是代码..
---------socket1.proto-------
message socket_packet {
required int32 d_size=1;
required string data=2;
}
----------protocolclient.cpp-----
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include "socket1.pb.h"
#include <iostream>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
std::streampos fileSize( const char* filePath ){
std::streampos fsize = 0;
std::ifstream file( filePath, std::ios::binary );
fsize = file.tellg();
file.seekg( 0, std::ios::end );
fsize = file.tellg() - fsize;
file.close();
return fsize;
}
using namespace google::protobuf::io;
using namespace std;
int main(int argv, char** argc){
/* Coded output stream */
socket_packet payload ;
int bytes_read;
std::streampos a1;
a1=filesize("test.txt");
payload.set_d_size(a1);
char *temp=new char[a1];
FILE *f = fopen("test.txt", "r");
bytes_read=fread(temp,sizeof(char),600000,f);
fclose(f);
payload.set_data(temp);
delete temp;
cout<<"size after serilizing is "<<payload.ByteSize()<<endl;
int siz = payload.ByteSize()+4;
char *pkt = new char [siz];
google::protobuf::io::ArrayOutputStream aos(pkt,siz);
CodedOutputStream *coded_output = new CodedOutputStream(&aos);
coded_output->WriteVarint32(payload.ByteSize());
payload.SerializeToCodedStream(coded_output);
int host_port= 1101;
char* host_name="127.0.0.1";
struct sockaddr_in my_addr;
char buffer[1024];
int bytecount;
int buffer_len=0;
int hsock;
int * p_int;
int err;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error initializing socket %d\n",errno);
goto FINISH;
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n",errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = inet_addr(host_name);
if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
if((err = errno) != EINPROGRESS){
fprintf(stderr, "Error connecting socket %d\n", errno);
goto FINISH;
}
}
for (int i =0;i<10000;i++){
for (int j = 0 ;j<10;j++) {
if( (bytecount=send(hsock, (void *) pkt,siz,0))== -1 ) {
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}
printf("Sent bytes %d\n", bytecount);
usleep(1);
}
}
delete pkt;
FINISH:
close(hsock);
return 0;
}
------------errors---------------
protocolclient.cpp:(.text+0x19d): undefined reference to `socket_packet::socket_packet()'
protocolclient.cpp:(.text+0x289): undefined reference to `socket_packet::ByteSize() const'
protocolclient.cpp:(.text+0x2c0): undefined reference to `socket_packet::ByteSize() const'
protocolclient.cpp:(.text+0x301): undefined reference to `google::protobuf::io::ArrayOutputStream::ArrayOutputStream(void*, int, int)'
protocolclient.cpp:(.text+0x320): undefined reference to `google::protobuf::io::CodedOutputStream::CodedOutputStream(google::protobuf::io::ZeroCopyOutputStream*)'
protocolclient.cpp:(.text+0x336): undefined reference to `socket_packet::ByteSize() const'
protocolclient.cpp:(.text+0x349): undefined reference to `google::protobuf::io::CodedOutputStream::WriteVarint32(unsigned int)'
protocolclient.cpp:(.text+0x362): undefined reference to `google::protobuf::MessageLite::SerializeToCodedStream(google::protobuf::io::CodedOutputStream*) const'
protocolclient.cpp:(.text+0x60a): undefined reference to `google::protobuf::io::ArrayOutputStream::~ArrayOutputStream()'
protocolclient.cpp:(.text+0x619): undefined reference to `socket_packet::~socket_packet()'
protocolclient.cpp:(.text+0x64e): undefined reference to `google::protobuf::io::ArrayOutputStream::~ArrayOutputStream()'
protocolclient.cpp:(.text+0x662): undefined reference to `socket_packet::~socket_packet()'
/tmp/ccO6KTWG.o: In function `socket_packet::set_data(char const*)':
protocolclient.cpp:(.text._ZN13socket_packet8set_dataEPKc[_ZN13socket_packet8set_dataEPKc]+0x29): undefined reference to `google::protobuf::internal::kEmptyString'
collect2: error: ld returned 1 exit status
--------------protocolserver.cpp-----------------
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>
#include "socket1.pb.h"
#include<fstream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
using namespace std;
using namespace google::protobuf::io;
void* SocketHandler(void*);
int main(int argv, char** argc)
{
int host_port= 1101;
struct sockaddr_in my_addr;
int hsock;
int * p_int ;
int err;
socklen_t addr_size = 0;
int* csock;
sockaddr_in sadr;
pthread_t thread_id=0;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error initializing socket %d\n", errno);
goto FINISH;
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n", errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY ;
if( bind( hsock, (sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",errno);
goto FINISH;
}
if(listen( hsock, 10) == -1 ){
fprintf(stderr, "Error listening %d\n",errno);
goto FINISH;
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while(true){
printf("waiting for a connection\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1){
printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
pthread_detach(thread_id);
}
else{
fprintf(stderr, "Error accepting %d\n", errno);
}
}
FINISH:
free(csock);
return 0;
}
google::protobuf::uint32 readHdr(char *buf)
{
google::protobuf::uint32 size;
google::protobuf::io::ArrayInputStream ais(buf,4);
CodedInputStream coded_input(&ais);
coded_input.ReadVarint32(&size);//Decode the HDR and get the size
cout<<"size of payload is "<<size<<endl;
return size;
}
void readBody(int csock,google::protobuf::uint32 siz)
{
int bytecount;
socket_packet payload;
char buffer [siz+4];//size of the payload and hdr
//Read the entire buffer including the hdr
if((bytecount = recv(csock, (void *)buffer, 4+siz, MSG_WAITALL))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
}
cout<<"Second read byte count is "<<bytecount<<endl;
//Assign ArrayInputStream with enough memory
google::protobuf::io::ArrayInputStream ais(buffer,siz+4);
CodedInputStream coded_input(&ais);
//Read an unsigned integer with Varint encoding, truncating to 32 bits.
coded_input.ReadVarint32(&siz);
//After the message's length is read, PushLimit() is used to prevent the CodedInputStream
//from reading beyond that length.Limits are used when parsing length-delimited
//embedded messages
google::protobuf::io::CodedInputStream::Limit msgLimit = coded_input.PushLimit(siz);
//De-Serialize
payload.ParseFromCodedStream(&coded_input);
//Once the embedded message has been parsed, PopLimit() is called to undo the limit
coded_input.PopLimit(msgLimit);
//Print the message
cout<<"Message is "<<payload.DebugString();
}
void* SocketHandler(void* lp){
int *csock = (int*)lp;
char buffer[4];
int bytecount=0;
string output,pl;
socket_packet logp;
memset(buffer, '\0', 4);
while (1) {
//Peek into the socket and get the packet size
if((bytecount = recv(*csock,
buffer,
4, MSG_PEEK))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
}else if (bytecount == 0)
break;
cout<<"First read byte count is "<<bytecount<<endl;
readBody(*csock,readHdr(buffer));
}
}
-----error----
/usr/bin/ld: /tmp/ccQmwjxg.o: undefined reference to symbol 'pthread_create@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
答案 0 :(得分:0)
看起来您忘记链接protobuf库。尝试将protobuf库路径添加到LD_LIBRARY_PATH
并使用以下代码编译代码:
g++ protocolclient.cpp socket1.pb.cc -lprotobuf -lpthread -o protoclient
或者您可以在构建时指定库搜索路径:
g++ protocolclient.cpp socket1.pb.cc -L/path/to/protobuf -lprotobuf -lpthread -o protoclient