日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信

發(fā)布時(shí)間:2023/12/20 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://blog.csdn.net/whuancai/article/details/11994341

如何在Windows環(huán)境下的VS中安裝使用Google Protobuf完成SOCKET通信

原文出自:http://blog.csdn.net/monkey_d_meng/article/details/5894910

尊重作者:MONKEY_D_MENG


?

最近一段時(shí)間,由于項(xiàng)目的需要,接觸到了Protobuf這個(gè)東東,在Linux環(huán)境下,體驗(yàn)了一把,感覺(jué)挺不錯(cuò),很方便,且高效。是一個(gè)非常值得學(xué)習(xí)掌握和應(yīng)用的數(shù)據(jù)抽象、平臺(tái)無(wú)關(guān)、功能強(qiáng)大、…(此處省略1000字)的開(kāi)源工具。

Google雖然把Protobuf做成了跨平臺(tái)、跨語(yǔ)言,但作為微軟的死對(duì)頭,它在readme.txt文件的第一句話(huà)就表明了態(tài)度:為了考慮部分MSVC的用戶(hù),Protobuf提供了針對(duì)VS的安裝說(shuō)明,但Protobuf最好用于Unix環(huán)境下。

在上一篇博客中,我介紹了如何在Linux環(huán)境下安裝Protobuf,現(xiàn)在讓我們了解一下Windows環(huán)境下,如何在VS中使用Protobuf,注意是VS,在VC6的環(huán)境下,我搞弄了一個(gè)晚上都沒(méi)成功,所以推薦VS2005或者以上版本:

?

1.下載protobuff,我下的是2.3.0版本

最新的protobuf可以到Google Code上下載:http://code.google.com/p/protobuf/downloads/list

當(dāng)前版本為2.3.0,下載兩個(gè)壓縮包:protoc-2.3.0-win32.zip和protobuf-2.3.0.zip,前者是protobuf的編譯器,后者包含了有三程序語(yǔ)言的開(kāi)發(fā)包。

?

2.解壓

首先解壓protoc-2.3.0-win32.zip,把protoc.exe文件放到path路徑中,最簡(jiǎn)單的做法就是把這個(gè)文件拷貝到C:/WINDOWS目錄下。

解壓protobuf-2.3.0.zip文件,將文件加壓到C盤(pán)根目錄,主文件位于C:/protobuf-2.3.0/protobuf-2.3.0目錄下。

?

3.安裝操作

(1)使用VS2005編譯proto,VS工程目錄位于vsprojects目錄中,工程名字為“protobuf.sln”。

?

(2)選擇“生成”à“生成解決方案”選項(xiàng)進(jìn)行編譯,編譯過(guò)程中可能會(huì)由于編譯的順序報(bào)錯(cuò)誤,可以使用手工逐個(gè)順序編譯生成,可能會(huì)比較順利。按照下圖的順序,右鍵“重新生成”,逐個(gè)編譯。但是我在實(shí)習(xí)操作過(guò)程中,libprotobuf-lite工程重來(lái)都沒(méi)有成功編譯通過(guò)過(guò)。淡定先,這個(gè)不會(huì)影響大局的。

?


(3)編譯完成會(huì)在目錄vsprojects下的Debug目錄中生成lib和exe文件。

生成清單如下:

exe文件:

2010-04-15??09:51?????????950,272 lite-test.exe

2010-04-15??09:50?????????3,219,456 protoc.exe

2010-04-15??09:48?????????9,228,288 tests.exe

2010-04-15??09:56?????????2,519,040 test_plugin.exe

?

lib文件:

2010-04-15??09:50????????2,685,922 libprotobuf-lite.lib

2010-04-15??09:56????????24,100,794 libprotobuf.lib

2010-04-15??09:56????????17,302,068 libprotoc.lib

其實(shí)我在測(cè)試過(guò)程中,lite-test.exe和libprotobuf-lite.lib并沒(méi)有生成,因?yàn)榫幾g錯(cuò)誤了,但這并不影響大局,淡定先。

?

(4)OK,至此,我們已經(jīng)完成了編譯工作,下面需要進(jìn)行的是protobuf的測(cè)試。我們需要使用到之前VS編譯出來(lái)的libprotobuf.lib和libprotoc.lib完成一個(gè)C/S結(jié)構(gòu)的SOCKET通信測(cè)試。

?

àProtobuf的測(cè)試

在VS2005下,創(chuàng)建兩個(gè)新的工程,分別命名為server和client,每個(gè)工程都需要引用protobuf的頭文件和lib文件。

一、添加protobuf頭文件操作:右擊項(xiàng)目à屬性à配置屬性àC/C++à常規(guī)?(也命令行可在中添加)。具體路徑:C:/protobuf-2.3.0/protobuf-2.3.0/src

二、添加protobuf的lib文件操作:右擊項(xiàng)目à屬性à配置屬性à鏈接器à常規(guī)(也可在命令行中添加)。具體路徑:C:/protobuf-2.3.0/protobuf-2.3.0/vsprojects/Debug

三、CMD窗口下編譯生成頭文件:

C:/protobuf-2.3.0/protobuf-2.3.0/examples>protoc -I=./ --cpp_out=./ people.proto

將proto文件生成的文件放到當(dāng)前目錄。

我們得到了兩個(gè)文件生:people.pb.h和people.pb.cc

?

people.proto文件內(nèi)容如下:

[cpp]?view plaincopy
  • package?CPFS;?????
  • message?People??
  • {?????
  • ??required?string?name?=?1;?????
  • ??required?int32?id?=?2;?????
  • ??required?string?email?=?3;?????
  • }??
  • ?

    ?

    四、server和client端源代碼:

    server端源代碼:

    [cpp]?view plaincopy
  • #include?"common/op_socket.h"??
  • #include?"people.pb.h"??
  • #pragma?comment(lib,?"libprotobuf.lib")??
  • #pragma?comment(lib,?"libprotoc.lib")??
  • using?namespace?std;??
  • int?main()?????
  • {?????
  • ????GOOGLE_PROTOBUF_VERIFY_VERSION;??
  • ????OP_SOCKET?server_sockfd;??
  • ????OP_SOCKET?new_server_sockfd;??
  • ????OP_SOCKADDR_IN?server_addr;??
  • ????OP_SOCKADDR_IN?client_addr;??
  • ????OP_SOCKLEN_T?sin_size;??
  • ????char?buffer[BUFFER_SIZE?+?1];??
  • ????int?bytes;??
  • ????string?str;??
  • ????string?data;??
  • ????CPFS::People?p;??
  • #ifdef?WIN32??
  • ????WSADATA??Ws;??
  • ????//Init?Windows?Socket??
  • ????if?(WSAStartup(MAKEWORD(2,2),?&Ws)?!=?0)??
  • ????{??
  • ????????fprintf(stderr,?"Init?Windows?Socket?Failed::%s",?GetLastError());??
  • ????????return?EXIT_FAILURE;??
  • ????}??
  • #endif??
  • ????server_sockfd?=?op_socket(AF_INET,?SOCK_STREAM,?0);???
  • ????op_set_sockaddr_in(server_addr,?AF_INET,?htons(INADDR_ANY),?htons(OP_PORT));??
  • ????op_bind(server_sockfd,?(struct?sockaddr?*)&server_addr,?sizeof(struct?sockaddr));?????
  • ????op_listen(server_sockfd,?LISTEN_QUEUE);?????
  • ????
  • ????while(1)??
  • ????{?????
  • ????????sin_size?=?sizeof(struct?sockaddr_in);??
  • ????????new_server_sockfd?=?op_accept(server_sockfd,?(struct?sockaddr?*)&client_addr,?&sin_size);??
  • ????
  • ????????bytes?=?op_recv(new_server_sockfd,?buffer,?BUFFER_SIZE,?0);??
  • ????????buffer[bytes]?=?'/0';??
  • ????????str?=?buffer;??
  • ????????cout?<<?"You?got?a?message?from?"?<<?inet_ntoa(client_addr.sin_addr)?<<?endl;??
  • ????????cout?<<?"client_addr?Message:?"?<<?str?<<?endl;??
  • ????????if(str?==?"get")??
  • ????????{??
  • ????????????p.set_id(1);??
  • ????????????????p.set_name("monkey");??
  • ????????????????p.set_email("mokeydong@gmail.com");??
  • ????????????????p.SerializeToString(&data);??
  • ????????????char?dst[BUFFER_SIZE];??
  • ????????????strcpy(dst,?data.c_str());??
  • ????????????????op_send(new_server_sockfd,?dst,?sizeof(dst),?0);??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????op_send(new_server_sockfd,?"Fucking?client_addr!/n",?16,?0);??
  • ????????}??
  • ????????op_close(new_server_sockfd);??
  • ????}?????
  • ????op_close(server_sockfd);??
  • ????google::protobuf::ShutdownProtobufLibrary();??
  • ????getchar();??
  • #ifdef?WIN32??
  • ????WSACleanup();??
  • #endif??
  • ????return?EXIT_SUCCESS;??
  • }??
  • client源代碼:

    ?

    [cpp]?view plaincopy
  • #include?"common/op_socket.h"??
  • #include?"people.pb.h"??
  • #pragma?comment(lib,?"libprotobuf.lib")??
  • #pragma?comment(lib,?"libprotoc.lib")??
  • using?namespace?std;??
  • int?main(int?argc,?char?**argv)?????
  • {??
  • ????GOOGLE_PROTOBUF_VERIFY_VERSION;??
  • ????OP_SOCKET?client_sockfd;??
  • ????OP_SOCKADDR_IN?server_addr;??
  • ????OP_SOCKADDR_IN?client_addr;??
  • ????char?buffer[BUFFER_SIZE?+?1];??
  • ????int?bytes;??
  • ????CPFS::People?p;??
  • ????if?(argc?!=?2)??
  • ????{??
  • ????????printf("Usage:?%s?/"COMMAND/"/n",argv[0]);??
  • ????????exit(0);??
  • ????}??
  • #ifdef?WIN32??
  • ????WSADATA??Ws;??
  • ????//Init?Windows?Socket??
  • ????if?(WSAStartup(MAKEWORD(2,2),?&Ws)?!=?0)??
  • ????{??
  • ????????fprintf(stderr,?"Init?Windows?Socket?Failed::%s",?GetLastError());??
  • ????????return?EXIT_FAILURE;??
  • ????}??
  • #endif??
  • ????client_sockfd?=?op_socket(AF_INET,?SOCK_STREAM,?0);??
  • ????op_set_sockaddr_in(server_addr,?AF_INET,?op_inet_addr(DEFAULT_SERVER_IP),?htons(OP_PORT));??
  • ????op_connect(client_sockfd,?(struct?sockaddr?*)&server_addr,?sizeof(struct?sockaddr));??
  • ????op_send(client_sockfd,?argv[1],?20,?0);??
  • ????bytes?=?op_recv(client_sockfd,?buffer,?BUFFER_SIZE,?0);??
  • ????buffer[bytes]?=?'/0';??
  • ????string?data?=?buffer;??
  • ????p.ParseFromString(data);??
  • ????cout?<<?"Name:?"?<<?p.name()?<<?endl;??
  • ????cout?<<?"ID:?"?<<?p.id()?<<?endl;??
  • ????cout?<<?"Email:?"?<<?p.email()?<<?endl;??
  • ????op_close(client_sockfd);??
  • #ifdef?WIN32??
  • ????WSACleanup();??
  • #endif??
  • ????google::protobuf::ShutdownProtobufLibrary();??
  • ????return?EXIT_SUCCESS;??
  • }??
  • 五、因?yàn)樯鲜鰞蓚€(gè)代碼用到了我寫(xiě)了一個(gè)初級(jí)版本的SOCKET跨平臺(tái)的庫(kù),這里貼出來(lái),很齪,但還可以用,小弟也才開(kāi)始寫(xiě)socket程序。這個(gè)庫(kù)文件要放到common/目錄下面。

    op_socket.h源代碼:

    ?

    [cpp]?view plaincopy
  • #ifndef?OP_SOCKET_H_??
  • #define?OP_SOCKET_H_??
  • #include?<stdio.h>??
  • #include?<errno.h>??
  • #include?<string.h>??
  • #include?<stdlib.h>??
  • #include?<iostream>??
  • #include?<string>??
  • #ifndef?WIN32??
  • ????#include?<sys/types.h>??
  • ????#include?<sys/wait.h>??
  • ????#include?<sys/socket.h>??
  • ????#include?<arpa/inet.h>??
  • ????#include?<netinet/in.h>??
  • ????#include?<signal.h>??
  • ????#include?<netdb.h>??
  • ????#include?<unistd.h>??
  • ????#include?<fcntl.h>??
  • #else??
  • ????#include?<winsock2.h>??
  • ????#pragma?comment(lib,?"ws2_32.lib")??
  • #endif??
  • //?Linux??
  • #ifndef?WIN32??
  • ????#define?OP_SOCKET???????????????int??
  • ????#define?OP_SOCKADDR_IN??????????struct?sockaddr_in??
  • ????#define?OP_SOCKADDR?????????????struct?sockaddr??
  • ????#define?OP_SOCKLEN_T????????????socklen_t??
  • //?Windows??
  • #else??
  • ????#define?OP_SOCKET???????????????SOCKET??
  • ????#define?OP_SOCKADDR_IN??????????SOCKADDR_IN??
  • ????#define?OP_SOCKADDR?????????????SOCKADDR??
  • ????#define?OP_SOCKLEN_T????????????int?FAR??
  • #endif??
  • #define?OP_PORT?????????????????????8888??
  • #define?BUFFER_SIZE?????????????????1024??
  • #define?LISTEN_QUEUE????????????????20??
  • #define?MD5_SIZE????????????????????32??
  • #define?FILE_PATH_MAX_SIZE??????????512??
  • #define?FILE_NAME_MAX_SIZE??????????260??
  • #define?FILE_FULL_NAME_MAX_SIZE?????1024??
  • #define?HOST????????????????????????"localhost"??
  • #define?DEFAULT_SERVER_IP???????????"127.0.0.1"??
  • #ifndef?WIN32??
  • ????#define?CLI_FILE_PATH???????????"/tmp/data/client/"?//?客戶(hù)端存儲(chǔ)文件的初始化路徑??
  • ????#define?SERV_FILE_PATH??????????"/tmp/data/server/"?//?服務(wù)器端存儲(chǔ)文件的初始化路徑??
  • #else??
  • ????#define?CLI_FILE_PATH???????????"D://download//"????//?客戶(hù)端存儲(chǔ)文件的初始化路徑??
  • ????#define?SERV_FILE_PATH??????????"D://data//"????????//?客戶(hù)端存儲(chǔ)文件的初始化路徑??
  • #endif??
  • //?把一段內(nèi)存區(qū)的內(nèi)容全部設(shè)置為??
  • void?op_clean_buffer(void?*buffer,?int?len);??
  • //?設(shè)置sockaddr_in,?internet協(xié)議族,?INADDR_ANY表示自動(dòng)獲取本機(jī)地址??
  • void?op_set_sockaddr_in(OP_SOCKADDR_IN?&addr,?short?op_sin_family,?unsigned?long?op_s_addr,?unsigned?short?op_sin_port);??
  • //?創(chuàng)建用于internet的流協(xié)議(TCP)socket,?用server_socket代表服務(wù)器socket??
  • int?op_socket(int?domain,?int?type,?int?protocol);??
  • //?接受一個(gè)到server_socket代表的socket的一個(gè)連接??
  • //?如果沒(méi)有連接請(qǐng)求,就等待到有連接請(qǐng)求--這是accept函數(shù)的特性??
  • //?accept函數(shù)返回一個(gè)新的socket,?這個(gè)socket(new_server_socket)用于同連接到的客戶(hù)的通信??
  • //?new_server_socket代表了服務(wù)器和客戶(hù)端之間的一個(gè)通信通道??
  • //?accept函數(shù)把連接到的客戶(hù)端信息填寫(xiě)到客戶(hù)端的socket地址結(jié)構(gòu)client_addr中??
  • int?op_accept(OP_SOCKET?sockfd,?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?*addrlen);??
  • //?IP的點(diǎn)分十記轉(zhuǎn)化為IP的結(jié)構(gòu)體??
  • unsigned?long?op_inet_addr(const?char?*dst);??
  • //?向服務(wù)器發(fā)起連接,連接成功后client_socket代表了客戶(hù)機(jī)和服務(wù)器的一個(gè)socket連接??
  • int?op_connect(OP_SOCKET?sockfd,?const?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?addrlen);??
  • //?addr指定的地址分配給與文件描述符socket關(guān)聯(lián)的未命名套接字??
  • int?op_bind(OP_SOCKET?sockfd,?const?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?addrlen);??
  • //?監(jiān)聽(tīng)client請(qǐng)求,backlog指定最大連接數(shù)??
  • int?op_listen(OP_SOCKET?sockfd,?int?backlog);??
  • //?send發(fā)送消息??
  • int?op_send(OP_SOCKET?sockfd,?const?char?*buffer,?size_t?len,?int?flags);??
  • //?recv接收消息??
  • int?op_recv(OP_SOCKET?sockfd,?char?*buffer,?size_t?len,?int?flags);??
  • //?關(guān)閉socket或文件指針??
  • FILE*?op_fopen(const?char?*path,?const?char?*mode);??
  • //?打開(kāi)文件??
  • int?op_close(OP_SOCKET?sockfd);??
  • //?關(guān)閉文件指針??
  • int?op_fclose(FILE?*stream);??
  • //?休眠函數(shù)??
  • void?op_sleep(int?micro_seconds);??
  • //?字符串比較函數(shù)??
  • int?op_stricmp(char?*s1,char?*?s2);??
  • #endif??
  • op_socket.cpp源文件代碼:

    ?

    [cpp]?view plaincopy
  • #include?"op_socket.h"??
  • //?把一段內(nèi)存區(qū)的內(nèi)容全部設(shè)置為??
  • void?op_clean_buffer(void?*buffer,?int?len)??
  • {??
  • #ifndef?WIN32??
  • ????bzero(buffer,?len);??
  • #else??
  • ????memset(buffer,?0,?len);??
  • #endif??
  • }??
  • //?設(shè)置sockaddr_in??
  • void?op_set_sockaddr_in(OP_SOCKADDR_IN?&addr,?short?op_sin_family,?unsigned?long?op_s_addr,?unsigned?short?op_sin_port)??
  • {??
  • ????op_clean_buffer(&addr,?sizeof(addr));??
  • ????addr.sin_family?=?op_sin_family;??
  • ????addr.sin_addr.s_addr?=?op_s_addr;??
  • ????addr.sin_port?=?op_sin_port;??
  • }??
  • //?創(chuàng)建socket??
  • int?op_socket(int?domain,?int?type,?int?protocol)??
  • {??
  • ????int?sockfd;??
  • #ifndef?WIN32??
  • ????if?((sockfd?=?socket(domain,?type,?protocol))?<?0)??
  • #else??
  • ????if?((sockfd?=?socket(domain,?type,?protocol))?==?INVALID_SOCKET)??
  • #endif??
  • ????{??
  • ????????fprintf(stderr,?"op_socket?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?sockfd;??
  • }??
  • //?接收客戶(hù)端的socket請(qǐng)求??
  • int?op_accept(OP_SOCKET?sockfd,?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?*addrlen)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?accept(sockfd,?addr,?addrlen))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_accept?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?IP的點(diǎn)分十記轉(zhuǎn)化為IP的結(jié)構(gòu)體??
  • unsigned?long?op_inet_addr(const?char?*dst)??
  • {??
  • ????long?ret;??
  • ????if?((ret?=?inet_addr(dst))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_inet_addr?error?for?%s/n",?dst);??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?(unsigned?long)ret;??
  • }??
  • //?sockfd指定的套接字連接到addr指定的服務(wù)器套接字??
  • int?op_connect(OP_SOCKET?sockfd,?const?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?addrlen)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?connect(sockfd,?addr,?addrlen))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_connect?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?addr指定的地址分配給與文件描述符socket關(guān)聯(lián)的未命名套接字??
  • int?op_bind(OP_SOCKET?sockfd,?const?OP_SOCKADDR?*addr,?OP_SOCKLEN_T?addrlen)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?bind(sockfd,?addr,?addrlen))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_bind?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?監(jiān)聽(tīng)client請(qǐng)求,backlog指定最大連接數(shù)??
  • int?op_listen(OP_SOCKET?sockfd,?int?backlog)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?listen(sockfd,?backlog))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_listen?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?send發(fā)送消息??
  • int?op_send(OP_SOCKET?sockfd,?const?char?*buffer,?size_t?len,?int?flags)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?send(sockfd,?buffer,?len,?flags))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_send?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?recv接收消息??
  • int?op_recv(OP_SOCKET?sockfd,?char?*buffer,?size_t?len,?int?flags)??
  • {??
  • ????size_t?ret;??
  • ????op_clean_buffer(buffer,?len);??
  • ????if?((ret?=?recv(sockfd,?buffer,?len,?flags))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_recv?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?關(guān)閉socket或文件指針??
  • int?op_close(OP_SOCKET?sockfd)??
  • {??
  • ????int?ret;??
  • #ifndef?WIN32??
  • ????if?((ret?=?close(sockfd))?<?0)??
  • #else??
  • ????if((ret?=?closesocket(sockfd))?<?0)??
  • #endif??
  • ????{??
  • ????????fprintf(stderr,?"op_close?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?打開(kāi)文件??
  • FILE*?op_fopen(const?char?*path,?const?char?*mode)??
  • {??
  • ????FILE?*fp?=?fopen(path,?mode);??
  • ????if?(NULL?==?fp)??
  • ????{??
  • ????????printf("File:/t%s?Can?Not?Open?To?Write/n",?path);??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?fp;??
  • }??
  • //?關(guān)閉文件指針??
  • int?op_fclose(FILE?*stream)??
  • {??
  • ????int?ret;??
  • ????if?((ret?=?fclose(stream))?<?0)??
  • ????{??
  • ????????fprintf(stderr,?"op_fclose?error/n");??
  • ????????exit(EXIT_FAILURE);??
  • ????}??
  • ????return?ret;??
  • }??
  • //?休眠函數(shù),對(duì)于usleep為微秒級(jí)別,對(duì)于Sleep為毫秒級(jí)別??
  • void?op_sleep(int?micro_seconds)??
  • {??
  • #ifndef?WIN32??
  • ????usleep(micro_seconds);??
  • #else??
  • ????Sleep(micro_seconds);??
  • #endif??
  • }??
  • //?字符串比較函數(shù)??
  • int?op_stricmp(char?*s1,char?*?s2)??
  • {??
  • #ifndef?WIN32??
  • ????return?strcasecmp(s1,?s2);??
  • #else??
  • ????return?stricmp(s1,?s2);??
  • #endif??
  • }??
  • 六、完成了上述的操作之后,就可以分別對(duì)client和server端進(jìn)行編譯了,先啟動(dòng)server端服務(wù)器,然后用命令行的形式運(yùn)行client端,就可以成功了吧。哈哈!我們來(lái)看一下使用protobuf進(jìn)行socket通信的實(shí)際效果!給大家截個(gè)圖!

    ?

    ?

    ?

    最近項(xiàng)目緊,沒(méi)空時(shí)間來(lái)好好寫(xiě)博客,只能粗略記錄一下,等實(shí)習(xí)結(jié)束后,要把這段時(shí)間的所學(xué)所感好好總結(jié)下來(lái)。

    順便說(shuō)一下,op_socket這個(gè)SOCKET是跨平臺(tái)的,寫(xiě)個(gè)makefile可以直接在UNIX環(huán)境下運(yùn)行的,咳咳,寫(xiě)的太齪了大家見(jiàn)笑了。。。


    總結(jié)

    以上是生活随笔為你收集整理的如何在Windows环境下的VS中安装使用Google Protobuf完成SOCKET通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。