2016-12-30 13 views
1

Я написал код C++, используя буфер протокола google, но во время работы он показывает ошибку «не объявлен в этой области» почти на каждой строке. Я также включил требуемые заголовки, я думаю Мне не хватает одного из шагов, пожалуйста, помогите. Вот код.Google Protocol Буферный сокет cclient

---------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 '[email protected]@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

могли бы вы предоставили более подробную информацию о компиляции ? С чем вы его скомпилируете? Какие варианты вы используете? – pSoLT

+0

Я установил protobuff компилятор, используя sudo apt-get install protobuf компилятор и создал socket1.pb.h и socket1.pb.cc. Я загрузил пакет protobuf master и сохранил его в той же папке. Теперь, когда я делаю g ++ protocolclient.cpp, он показывает ошибки. –

ответ

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

+0

Не могли бы вы рассказать мне, как добавить путь библиотеки protobuf к LD_LLIBRARY_PATH .... Должен ли я указать путь к главной папке Protobuff .... Пожалуйста, помогите .. –

+0

Во-первых, проверьте, нет ли уже там - это может быть если вы установили его с помощью apt-get, просто запустите компиляцию, как описано. Если он не использует экспорт LD_LIBRARY_PATH =/path/to/protobuf/library: $ LD_LIBRARY_PATH – pSoLT

+0

Эй, я сделал оба пути ... он не работает ... он дает эти ошибки. –