Socket编程+Google Protocol搭建简单的客户端服务器方式1
来源:互联网 发布:mac os x 原版dmg 编辑:程序博客网 时间:2024/06/07 20:11
一种比较搓的方式利用Google Protoco来进行客户端服务器数据通信
A客户端模块:
1.新建一个win32控制台应用程序,是空项目,名字为MyCient
2. Google Protocol环境配置(详细配置看我文章http://blog.csdn.net/dugaoda/article/details/50342449)
2.1.
2.2.添加lib文件到项目Debug下面
3.生成协议person. proto
内容为
package tutorial;
message Person {
required string name = 1;
required int32 age = 2;
optional string email = 3;
}
message msg
{
required int32 id = 1; // message ID
required int32 len = 2; //message Length
required bytes info = 3; //message content = 二进制方式.
}
得到person.pb.h和person.pb.cc
4.新建文件MyClient.cpp
同时添加文件person.pb.h和person.pb.cc
项目文件结构如下
5.编写MyClient.cpp文件内容
先直接贴上代码
// MyClient.cpp : 定义控制台应用程序的入口点。
//
#include "winsock2.h"
#include <iostream>
#include <fstream>
#include "person.pb.h"
#include "TCPPakDef.hpp"
#pragma comment(lib, "ws2_32.lib")
using namespace std;
using namespace tutorial;
BOOL RecvLine(SOCKET s, char *buf);
int main()
{
tutorial::Person PERSON;
const int BUF_SIZE = 1024;
WSADATA wsd;
SOCKET sHost;
SOCKADDR_IN servAddr;
char buf[BUF_SIZE]="";//接收数据缓冲区
char bufRecv[BUF_SIZE]="";
//截断后面的乱码输出
cout << endl << "1从服务器接受数据:" << buf;
cout << endl << "2从服务器接受数据:" << bufRecv;
int retVal;
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup failded!" << endl;
return 1;
}
//创建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
WSACleanup();//释放套接字资源
return -1;
}
//设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons((short)123);
int nServAddlen = sizeof(servAddr);
//连接服务器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == retVal)
{
cout << "connect failed" <<endl;
closesocket(sHost);
WSACleanup();
return -1;
}
while (true)
{
//向服务器发送数据
ZeroMemory(buf, BUF_SIZE);
cout << "向服务器发送数据:";
char buf123[BUF_SIZE]="";
cin >> buf123;
//使用google protobuf 将数据发送出去
//其实在每个MSG的头上面加上ID 在服务器上面解析出来就可以用了
PERSON.set_name("dugoada");
PERSON.set_age(123);
string data;
PERSON.SerializeToString(&data);
char dst[BUF_SIZE];
strcpy(dst, data.c_str());
retVal = send(sHost, dst, sizeof(dst), 0);
if (SOCKET_ERROR == retVal)
{
cout << "send failed!" << endl;
closesocket(sHost);//关闭套接字
WSACleanup();
return -1;
}
// 接收服务器端的数据
ZeroMemory(buf, BUF_SIZE);
recv(sHost, bufRecv, BUF_SIZE, 0);
cout << endl << "从服务器接受数据:" << bufRecv;
}
closesocket(sHost);//关闭套接字
WSACleanup();
return 0;
}
6.关键代码说明
//使用google protobuf 将数据发送出去
//其实在每个MSG的头上面加上ID 在服务器上面解析出来就可以用了
PERSON.set_name("dugoada");
PERSON.set_age(123);
//将PERSON的数据内容序列化到data中
string data;
PERSON.SerializeToString(&data);
//将data数据copy到dst中 发送的时候需要用到的是char类型的字符
char dst[BUF_SIZE];
strcpy(dst, data.c_str());
B 服务器模块:
环境配置部分跟客户端一样,代码不一样(注意)
1.编写MyServer.cpp文件内容
先直接贴上代码
// MyServer.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
using namespace std;
#include <iostream>
#include<fstream>
#include "TCPPakDef.hpp"
#include "person.pb.h"
using namespace tutorial;
int main()
{
tutorial::Person PERSON;
const int BUF_SIZE = 1024;
WSADATA wsd;
SOCKET sServer;
SOCKET sClient;
SOCKADDR_IN addrServ;
char buf[BUF_SIZE];
char sendBuf[BUF_SIZE];
int retVal;
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup failded!" << endl;
return 1;
}
//创建套接字
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
cout << "socket failed!" << endl;
WSACleanup();
return -1;
}
//服务器套接字地址信息设置
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(123);
addrServ.sin_addr.s_addr = INADDR_ANY;
//绑定
retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
cout << "bind failed!" << endl;
closesocket(sServer);
WSACleanup();
return -1;
}
//开始监听
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
cout << "listen failed!" << endl;
closesocket(sServer);
WSACleanup();
return -1;
}
//接受客户端请求
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR *)&addrClient, &addrClientlen);
if (INVALID_SOCKET == sClient)
{
cout << "accept failed!" << endl;
closesocket(sServer);
WSACleanup();
return -1;
}
//数据处理
while (true)
{
//接受客户端数据
ZeroMemory(buf, BUF_SIZE);
retVal = recv(sClient, buf, BUF_SIZE, 0);
//方法1 解析google protobuf
string data = buf;
PERSON.ParseFromString(data);
cout << "Name: " << PERSON.name() << endl;
cout << "Age: " << PERSON.age() << endl;
if (SOCKET_ERROR == retVal)
{
cout << "recv, failed!" << endl;
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -1;
}
if (buf[0] == '0')
break;
cout << "客户端发送的数据:" << buf << endl;
cout << "向客户端发送数据:";
cin >> sendBuf;
send(sClient, sendBuf, strlen(sendBuf), 0);
}
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return 0;
}
6.关键代码说明
//方法1 解析google protobuf
//将数据从data解析到PERSON中
string data = buf;
PERSON.ParseFromString(data);
//得到自己想要的数据
cout << "Name: " << PERSON.name() << endl;
cout << "Age: " << PERSON.age() << endl;
- Socket编程+Google Protocol搭建简单的客户端服务器方式1
- Socket编程+Google Protocol搭建简单的客户端服务器方式2
- 简单socket编程,服务器、客户端
- socket编程:简单TCP服务器/客户端编程
- socket编程:简单UDP服务器/客户端编程
- Linux socket编程-最简单的服务器和客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序
- socket编程:服务器与客户端简单交互的例子
- Linux socket编程-最简单的服务器和客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序 .
- Windows Socket 编程_ 简单的服务器/客户端程序
- linux socket 编程一:简单的服务器和客户端通信
- Windows Socket 编程_ 简单的服务器/客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序
- Windows Socket 编程_ 简单的服务器/客户端程序 .
- Windows Socket 编程_ 简单的服务器/客户端程序
- CString成员函数用法大全
- NSUserDefaults的基本使用
- 【Scikit-Learn】初试开源机器学习工具
- Git的详细使用教程
- maven
- Socket编程+Google Protocol搭建简单的客户端服务器方式1
- Xamarin.Forms教程下载安装JDK配置环境变量
- 什么是V-模式开发?与瀑布式开发个有什么优缺点?
- 数据结构面试题
- Unity3D中实现帧同步 - Part 1
- Hbase系统架构及数据结构
- pixhawk自学笔记之环境搭建注意细节
- Hbase Shell使用
- 现在认识的人越来越狡猾。