最近准备毕业,就一直闲着。在公司实习时候跟着华哥和强哥接触了googleprotobuf,感觉这东西是个好东西,但是当时网龙公司把底层都做好了,接触的就是直接调用他们做好的接口。自己也不懂socket之类的网络编程,现在准备往上海那边找工作,就自己琢磨琢磨下。
因为个人原因,我比较喜欢linux系统,就选用了linux平台的QT来做这个demo。用linux安装东西也方便很多。
首先我们来安装googleprotobuf
wget http://protobuf.googlecode.com/files/protobuf-你的版本号.tar.gz |
tar zxvf protobuf-你的版本号 .tar.gz |
cd protobuf- 你的版本号 |
./configure --prefix=/usr/ |
make |
sudo make install |
/sbin/ldconfig -v |
最后一条命令是为了避免在使用protoc命令时出现库的问题。
现在我们来写一个proto文件,命名为:QTPeople.proto,内容如下:
packageQTpeople;
messagePeople
{
required string name=1;
required int32 ID=2;
required string passwd=3;
}
现在我们需要生成h和cc文件,命令如下:
protoc-I=. --cpp_out=./ QTPeople.proto(这个命令的参数意义manprotoc就查到了)
QTPeople.pb.cc
QTPeople.pb.h
QTPeople.proto
现在我们使用QT来新建两个项目,分别命名为:QtprotoC、QtprotoS,并在pro文件里面添加LIBS +=-L /usr/lib-lprotobuf,
因为这个是测试的demo,我就直接使用项目生成的main文件,在main文件内include QTPeople.pb.h
文件。
QtprotoC的main文件内容如下:
#include <QCoreApplication>
/*
-----懂得沉默------
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <iostream>
#include<QDebug>
#include "QTPeople.pb.h"
#define MAXSIZE 1024
#define SERVERIP "127.0.0.1"
#define SERVERPORT 2236
#define DATA "this is guest"
using namespace std;
void Client()
{
int Mysock,recvbytes;
string data;
char buf[MAXSIZE];
struct sockaddr_in ServerAddr;
QTpeople::People peo;
peo.set_id(1002);
peo.set_name("def");
peo.set_passwd("1234567");
peo.SerializeToString(&data);
char sendmsg[MAXSIZE];
strcpy(sendmsg,data.c_str());
if((Mysock=socket(AF_INET,SOCK_STREAM,0))==-1)
{
qDebug()<<"Sockt error";
exit(-1);
}
bzero(&ServerAddr,sizeof(ServerAddr));
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(SERVERPORT);
ServerAddr.sin_addr.s_addr=inet_addr(SERVERIP);
if (connect(Mysock, (struct sockaddr *)&ServerAddr,sizeof(struct sockaddr)) == -1)
{
qDebug()<<"Connect error";
exit(-1);
}
write(Mysock,sendmsg,sizeof(sendmsg));
if((recvbytes=recv(Mysock,buf,MAXSIZE,0))==-1)
{
qDebug()<<"received error";
exit(-1);
}
qDebug()<<"sucess";
buf[recvbytes]=‘\0‘;
string getmsg=buf;
cout<<getmsg<<endl;
bool isGet=peo.ParseFromString(getmsg);
qDebug()<<isGet;
cout<<"id="<<peo.id()<<endl;
cout<<"name="<<peo.name()<<endl;
cout<<"passwd="<<peo.passwd()<<endl;
close(Mysock);
// google::protobuf::ShutdownProtobufLibrary();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Client();
return a.exec();
}
QtprotoSmain文件内容如下:
#include <QCoreApplication>
/*
-----懂得沉默------
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <iostream>
#include<QDebug>
#include "QTPeople.pb.h"
#define SERVPORT 2236
#define BACKLOG 10
#define MAXSIZE 1024
using namespace std;
void server() {
int sockfd, client_fd;
string data;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
QTpeople::People peo;
peo.set_id(1001);
peo.set_name("abc");
peo.set_passwd("7654321");
peo.SerializeToString(&data);
char sendmsg[MAXSIZE];
strcpy(sendmsg,data.c_str());
//创建套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) ==-1) {
perror("socket create failed!");
exit(1);
}
//绑定端口地址
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(SERVPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (struct sockaddr*) &my_addr, sizeof(my_addr))== -1) {
perror("bind error!");
exit(1);
}
//监听端口
if (listen(sockfd, BACKLOG) == -1) {
perror("listen error");
exit(1);
}
qDebug()<<"before while ok";
while (1) {
qDebug()<<"while first ok";
socklen_t sin_size = sizeof(remote_addr);
qDebug()<<"before accept ok";
/* if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr,&sin_size)) ==-1){
perror("accept error!");
continue;
}
*/
client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size);
qDebug()<<client_fd;
if(client_fd==-1)
{
perror("accept error");
continue;
}
qDebug()<<"accept ok";
// client_fd = accept(sockfd, (struct sockaddr *)&remote_addr,&sin_size);
printf("Received a connection from %s\n", (char*)inet_ntoa(remote_addr.sin_addr));
qDebug()<<"before fork ok";
//子进程段
if (!fork()) {
qDebug()<<"fork ok";
//接受client发送的请示信息
int rval;
char buf[MAXSIZE];
if ((rval = read(client_fd, buf, MAXSIZE)) < 0) {
perror("reading stream error!");
continue;
}
qDebug()<<"read ok";
buf[MAXSIZE]=‘\0‘;
string getmsg=buf;
bool isGet=peo.ParseFromString(getmsg);
qDebug()<<isGet;
cout<<"id="<<peo.id()<<endl;
cout<<"name="<<peo.name()<<endl;
cout<<"passwd="<<peo.passwd()<<endl;
//向client发送信息
if (send(client_fd,sendmsg, strlen(sendmsg), 0) == -1)
perror("send error!");
close(client_fd);
exit(0);
}
close(client_fd);
}
close(sockfd);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
server();
return a.exec();
}