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

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

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

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

尊重作者:MONKEY_D_MENG


 

最近一段时间,由于项目的需要,接触到了Protobuf这个东东,在Linux环境下,体验了一把,感觉挺不错,很方便,且高效。是一个非常值得学习掌握和应用的数据抽象、平台无关、功能强大、…(此处省略1000字)的开源工具。

Google虽然把Protobuf做成了跨平台、跨语言,但作为微软的死对头,它在readme.txt文件的第一句话就表明了态度:为了考虑部分MSVC的用户,Protobuf提供了针对VS的安装说明,但Protobuf最好用于Unix环境下。

在上一篇博客中,我介绍了如何在Linux环境下安装Protobuf,现在让我们了解一下Windows环境下,如何在VS中使用Protobuf,注意是VS,在VC6的环境下,我搞弄了一个晚上都没成功,所以推荐VS2005或者以上版本:

 

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

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

当前版本为2.3.0,下载两个压缩包:protoc-2.3.0-win32.zip和protobuf-2.3.0.zip,前者是protobuf的编译器,后者包含了有三程序语言的开发包。

 

2.解压

首先解压protoc-2.3.0-win32.zip,把protoc.exe文件放到path路径中,最简单的做法就是把这个文件拷贝到C:/WINDOWS目录下。

解压protobuf-2.3.0.zip文件,将文件加压到C盘根目录,主文件位于C:/protobuf-2.3.0/protobuf-2.3.0目录下。

 

3.安装操作

(1)使用VS2005编译proto,VS工程目录位于vsprojects目录中,工程名字为“protobuf.sln”。

 

(2)选择“生成”à“生成解决方案”选项进行编译,编译过程中可能会由于编译的顺序报错误,可以使用手工逐个顺序编译生成,可能会比较顺利。按照下图的顺序,右键“重新生成”,逐个编译。但是我在实习操作过程中,libprotobuf-lite工程重来都没有成功编译通过过。淡定先,这个不会影响大局的。

 


(3)编译完成会在目录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

其实我在测试过程中,lite-test.exe和libprotobuf-lite.lib并没有生成,因为编译错误了,但这并不影响大局,淡定先。

 

(4)OK,至此,我们已经完成了编译工作,下面需要进行的是protobuf的测试。我们需要使用到之前VS编译出来的libprotobuf.lib和libprotoc.lib完成一个C/S结构的SOCKET通信测试。

 

àProtobuf的测试

在VS2005下,创建两个新的工程,分别命名为server和client,每个工程都需要引用protobuf的头文件和lib文件。

一、添加protobuf头文件操作:右击项目à属性à配置属性àC/C++à常规 (也命令行可在中添加)。具体路径:C:/protobuf-2.3.0/protobuf-2.3.0/src

二、添加protobuf的lib文件操作:右击项目à属性à配置属性à链接器à常规(也可在命令行中添加)。具体路径: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文件生成的文件放到当前目录。

我们得到了两个文件生:people.pb.h和people.pb.cc

 

people.proto文件内容如下:

[cpp] view plaincopy
  1. package CPFS;     
  2. message People  
  3. {     
  4.   required string name = 1;     
  5.   required int32 id = 2;     
  6.   required string email = 3;     
  7. }  
 

 

四、server和client端源代码:

server端源代码:

[cpp] view plaincopy
  1. #include "common/op_socket.h"  
  2. #include "people.pb.h"  
  3. #pragma comment(lib, "libprotobuf.lib")  
  4. #pragma comment(lib, "libprotoc.lib")  
  5. using namespace std;  
  6. int main()     
  7. {     
  8.     GOOGLE_PROTOBUF_VERIFY_VERSION;  
  9.     OP_SOCKET server_sockfd;  
  10.     OP_SOCKET new_server_sockfd;  
  11.     OP_SOCKADDR_IN server_addr;  
  12.     OP_SOCKADDR_IN client_addr;  
  13.     OP_SOCKLEN_T sin_size;  
  14.     char buffer[BUFFER_SIZE + 1];  
  15.     int bytes;  
  16.     string str;  
  17.     string data;  
  18.     CPFS::People p;  
  19. #ifdef WIN32  
  20.     WSADATA  Ws;  
  21.     //Init Windows Socket  
  22.     if (WSAStartup(MAKEWORD(2,2), &Ws) != 0)  
  23.     {  
  24.         fprintf(stderr, "Init Windows Socket Failed::%s", GetLastError());  
  25.         return EXIT_FAILURE;  
  26.     }  
  27. #endif  
  28.     server_sockfd = op_socket(AF_INET, SOCK_STREAM, 0);   
  29.     op_set_sockaddr_in(server_addr, AF_INET, htons(INADDR_ANY), htons(OP_PORT));  
  30.     op_bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));     
  31.     op_listen(server_sockfd, LISTEN_QUEUE);     
  32.     
  33.     while(1)  
  34.     {     
  35.         sin_size = sizeof(struct sockaddr_in);  
  36.         new_server_sockfd = op_accept(server_sockfd, (struct sockaddr *)&client_addr, &sin_size);  
  37.     
  38.         bytes = op_recv(new_server_sockfd, buffer, BUFFER_SIZE, 0);  
  39.         buffer[bytes] = '/0';  
  40.         str = buffer;  
  41.         cout << "You got a message from " << inet_ntoa(client_addr.sin_addr) << endl;  
  42.         cout << "client_addr Message: " << str << endl;  
  43.         if(str == "get")  
  44.         {  
  45.             p.set_id(1);  
  46.                 p.set_name("monkey");  
  47.                 p.set_email("mokeydong@gmail.com");  
  48.                 p.SerializeToString(&data);  
  49.             char dst[BUFFER_SIZE];  
  50.             strcpy(dst, data.c_str());  
  51.                 op_send(new_server_sockfd, dst, sizeof(dst), 0);  
  52.         }  
  53.         else  
  54.         {  
  55.             op_send(new_server_sockfd, "Fucking client_addr!/n", 16, 0);  
  56.         }  
  57.         op_close(new_server_sockfd);  
  58.     }     
  59.     op_close(server_sockfd);  
  60.     google::protobuf::ShutdownProtobufLibrary();  
  61.     getchar();  
  62. #ifdef WIN32  
  63.     WSACleanup();  
  64. #endif  
  65.     return EXIT_SUCCESS;  
  66. }  

client源代码:

 

[cpp] view plaincopy
  1. #include "common/op_socket.h"  
  2. #include "people.pb.h"  
  3. #pragma comment(lib, "libprotobuf.lib")  
  4. #pragma comment(lib, "libprotoc.lib")  
  5. using namespace std;  
  6. int main(int argc, char **argv)     
  7. {  
  8.     GOOGLE_PROTOBUF_VERIFY_VERSION;  
  9.     OP_SOCKET client_sockfd;  
  10.     OP_SOCKADDR_IN server_addr;  
  11.     OP_SOCKADDR_IN client_addr;  
  12.     char buffer[BUFFER_SIZE + 1];  
  13.     int bytes;  
  14.     CPFS::People p;  
  15.     if (argc != 2)  
  16.     {  
  17.         printf("Usage: %s /"COMMAND/"/n",argv[0]);  
  18.         exit(0);  
  19.     }  
  20. #ifdef WIN32  
  21.     WSADATA  Ws;  
  22.     //Init Windows Socket  
  23.     if (WSAStartup(MAKEWORD(2,2), &Ws) != 0)  
  24.     {  
  25.         fprintf(stderr, "Init Windows Socket Failed::%s", GetLastError());  
  26.         return EXIT_FAILURE;  
  27.     }  
  28. #endif  
  29.     client_sockfd = op_socket(AF_INET, SOCK_STREAM, 0);  
  30.     op_set_sockaddr_in(server_addr, AF_INET, op_inet_addr(DEFAULT_SERVER_IP), htons(OP_PORT));  
  31.     op_connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));  
  32.     op_send(client_sockfd, argv[1], 20, 0);  
  33.     bytes = op_recv(client_sockfd, buffer, BUFFER_SIZE, 0);  
  34.     buffer[bytes] = '/0';  
  35.     string data = buffer;  
  36.     p.ParseFromString(data);  
  37.     cout << "Name: " << p.name() << endl;  
  38.     cout << "ID: " << p.id() << endl;  
  39.     cout << "Email: " << p.email() << endl;  
  40.     op_close(client_sockfd);  
  41. #ifdef WIN32  
  42.     WSACleanup();  
  43. #endif  
  44.     google::protobuf::ShutdownProtobufLibrary();  
  45.     return EXIT_SUCCESS;  
  46. }  

五、因为上述两个代码用到了我写了一个初级版本的SOCKET跨平台的库,这里贴出来,很龊,但还可以用,小弟也才开始写socket程序。这个库文件要放到common/目录下面。

op_socket.h源代码:

 

[cpp] view plaincopy
  1. #ifndef OP_SOCKET_H_  
  2. #define OP_SOCKET_H_  
  3. #include <stdio.h>  
  4. #include <errno.h>  
  5. #include <string.h>  
  6. #include <stdlib.h>  
  7. #include <iostream>  
  8. #include <string>  
  9. #ifndef WIN32  
  10.     #include <sys/types.h>  
  11.     #include <sys/wait.h>  
  12.     #include <sys/socket.h>  
  13.     #include <arpa/inet.h>  
  14.     #include <netinet/in.h>  
  15.     #include <signal.h>  
  16.     #include <netdb.h>  
  17.     #include <unistd.h>  
  18.     #include <fcntl.h>  
  19. #else  
  20.     #include <winsock2.h>  
  21.     #pragma comment(lib, "ws2_32.lib")  
  22. #endif  
  23. // Linux  
  24. #ifndef WIN32  
  25.     #define OP_SOCKET               int  
  26.     #define OP_SOCKADDR_IN          struct sockaddr_in  
  27.     #define OP_SOCKADDR             struct sockaddr  
  28.     #define OP_SOCKLEN_T            socklen_t  
  29. // Windows  
  30. #else  
  31.     #define OP_SOCKET               SOCKET  
  32.     #define OP_SOCKADDR_IN          SOCKADDR_IN  
  33.     #define OP_SOCKADDR             SOCKADDR  
  34.     #define OP_SOCKLEN_T            int FAR  
  35. #endif  
  36. #define OP_PORT                     8888  
  37. #define BUFFER_SIZE                 1024  
  38. #define LISTEN_QUEUE                20  
  39. #define MD5_SIZE                    32  
  40. #define FILE_PATH_MAX_SIZE          512  
  41. #define FILE_NAME_MAX_SIZE          260  
  42. #define FILE_FULL_NAME_MAX_SIZE     1024  
  43. #define HOST                        "localhost"  
  44. #define DEFAULT_SERVER_IP           "127.0.0.1"  
  45. #ifndef WIN32  
  46.     #define CLI_FILE_PATH           "/tmp/data/client/" // 客户端存储文件的初始化路径  
  47.     #define SERV_FILE_PATH          "/tmp/data/server/" // 服务器端存储文件的初始化路径  
  48. #else  
  49.     #define CLI_FILE_PATH           "D://download//"    // 客户端存储文件的初始化路径  
  50.     #define SERV_FILE_PATH          "D://data//"        // 客户端存储文件的初始化路径  
  51. #endif  
  52. // 把一段内存区的内容全部设置为  
  53. void op_clean_buffer(void *buffer, int len);  
  54. // 设置sockaddr_in, internet协议族, INADDR_ANY表示自动获取本机地址  
  55. void op_set_sockaddr_in(OP_SOCKADDR_IN &addr, short op_sin_family, unsigned long op_s_addr, unsigned short op_sin_port);  
  56. // 创建用于internet的流协议(TCP)socket, 用server_socket代表服务器socket  
  57. int op_socket(int domain, int type, int protocol);  
  58. // 接受一个到server_socket代表的socket的一个连接  
  59. // 如果没有连接请求,就等待到有连接请求--这是accept函数的特性  
  60. // accept函数返回一个新的socket, 这个socket(new_server_socket)用于同连接到的客户的通信  
  61. // new_server_socket代表了服务器和客户端之间的一个通信通道  
  62. // accept函数把连接到的客户端信息填写到客户端的socket地址结构client_addr中  
  63. int op_accept(OP_SOCKET sockfd, OP_SOCKADDR *addr, OP_SOCKLEN_T *addrlen);  
  64. // IP的点分十记转化为IP的结构体  
  65. unsigned long op_inet_addr(const char *dst);  
  66. // 向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接  
  67. int op_connect(OP_SOCKET sockfd, const OP_SOCKADDR *addr, OP_SOCKLEN_T addrlen);  
  68. // addr指定的地址分配给与文件描述符socket关联的未命名套接字  
  69. int op_bind(OP_SOCKET sockfd, const OP_SOCKADDR *addr, OP_SOCKLEN_T addrlen);  
  70. // 监听client请求,backlog指定最大连接数  
  71. int op_listen(OP_SOCKET sockfd, int backlog);  
  72. // send发送消息  
  73. int op_send(OP_SOCKET sockfd, const char *buffer, size_t len, int flags);  
  74. // recv接收消息  
  75. int op_recv(OP_SOCKET sockfd, char *buffer, size_t len, int flags);  
  76. // 关闭socket或文件指针  
  77. FILE* op_fopen(const char *path, const char *mode);  
  78. // 打开文件  
  79. int op_close(OP_SOCKET sockfd);  
  80. // 关闭文件指针  
  81. int op_fclose(FILE *stream);  
  82. // 休眠函数  
  83. void op_sleep(int micro_seconds);  
  84. // 字符串比较函数  
  85. int op_stricmp(char *s1,char * s2);  
  86. #endif  

op_socket.cpp源文件代码:

 

[cpp] view plaincopy
  1. #include "op_socket.h"  
  2. // 把一段内存区的内容全部设置为  
  3. void op_clean_buffer(void *buffer, int len)  
  4. {  
  5. #ifndef WIN32  
  6.     bzero(buffer, len);  
  7. #else  
  8.     memset(buffer, 0, len);  
  9. #endif  
  10. }  
  11. // 设置sockaddr_in  
  12. void op_set_sockaddr_in(OP_SOCKADDR_IN &addr, short op_sin_family, unsigned long op_s_addr, unsigned short op_sin_port)  
  13. {  
  14.     op_clean_buffer(&addr, sizeof(addr));  
  15.     addr.sin_family = op_sin_family;  
  16.     addr.sin_addr.s_addr = op_s_addr;  
  17.     addr.sin_port = op_sin_port;  
  18. }  
  19. // 创建socket  
  20. int op_socket(int domain, int type, int protocol)  
  21. {  
  22.     int sockfd;  
  23. #ifndef WIN32  
  24.     if ((sockfd = socket(domain, type, protocol)) < 0)  
  25. #else  
  26.     if ((sockfd = socket(domain, type, protocol)) == INVALID_SOCKET)  
  27. #endif  
  28.     {  
  29.         fprintf(stderr, "op_socket error/n");  
  30.         exit(EXIT_FAILURE);  
  31.     }  
  32.     return sockfd;  
  33. }  
  34. // 接收客户端的socket请求  
  35. int op_accept(OP_SOCKET sockfd, OP_SOCKADDR *addr, OP_SOCKLEN_T *addrlen)  
  36. {  
  37.     int ret;  
  38.     if ((ret = accept(sockfd, addr, addrlen)) < 0)  
  39.     {  
  40.         fprintf(stderr, "op_accept error/n");  
  41.         exit(EXIT_FAILURE);  
  42.     }  
  43.     return ret;  
  44. }  
  45. // IP的点分十记转化为IP的结构体  
  46. unsigned long op_inet_addr(const char *dst)  
  47. {  
  48.     long ret;  
  49.     if ((ret = inet_addr(dst)) < 0)  
  50.     {  
  51.         fprintf(stderr, "op_inet_addr error for %s/n", dst);  
  52.         exit(EXIT_FAILURE);  
  53.     }  
  54.     return (unsigned long)ret;  
  55. }  
  56. // sockfd指定的套接字连接到addr指定的服务器套接字  
  57. int op_connect(OP_SOCKET sockfd, const OP_SOCKADDR *addr, OP_SOCKLEN_T addrlen)  
  58. {  
  59.     int ret;  
  60.     if ((ret = connect(sockfd, addr, addrlen)) < 0)  
  61.     {  
  62.         fprintf(stderr, "op_connect error/n");  
  63.         exit(EXIT_FAILURE);  
  64.     }  
  65.     return ret;  
  66. }  
  67. // addr指定的地址分配给与文件描述符socket关联的未命名套接字  
  68. int op_bind(OP_SOCKET sockfd, const OP_SOCKADDR *addr, OP_SOCKLEN_T addrlen)  
  69. {  
  70.     int ret;  
  71.     if ((ret = bind(sockfd, addr, addrlen)) < 0)  
  72.     {  
  73.         fprintf(stderr, "op_bind error/n");  
  74.         exit(EXIT_FAILURE);  
  75.     }  
  76.     return ret;  
  77. }  
  78. // 监听client请求,backlog指定最大连接数  
  79. int op_listen(OP_SOCKET sockfd, int backlog)  
  80. {  
  81.     int ret;  
  82.     if ((ret = listen(sockfd, backlog)) < 0)  
  83.     {  
  84.         fprintf(stderr, "op_listen error/n");  
  85.         exit(EXIT_FAILURE);  
  86.     }  
  87.     return ret;  
  88. }  
  89. // send发送消息  
  90. int op_send(OP_SOCKET sockfd, const char *buffer, size_t len, int flags)  
  91. {  
  92.     int ret;  
  93.     if ((ret = send(sockfd, buffer, len, flags)) < 0)  
  94.     {  
  95.         fprintf(stderr, "op_send error/n");  
  96.         exit(EXIT_FAILURE);  
  97.     }  
  98.     return ret;  
  99. }  
  100. // recv接收消息  
  101. int op_recv(OP_SOCKET sockfd, char *buffer, size_t len, int flags)  
  102. {  
  103.     size_t ret;  
  104.     op_clean_buffer(buffer, len);  
  105.     if ((ret = recv(sockfd, buffer, len, flags)) < 0)  
  106.     {  
  107.         fprintf(stderr, "op_recv error/n");  
  108.         exit(EXIT_FAILURE);  
  109.     }  
  110.     return ret;  
  111. }  
  112. // 关闭socket或文件指针  
  113. int op_close(OP_SOCKET sockfd)  
  114. {  
  115.     int ret;  
  116. #ifndef WIN32  
  117.     if ((ret = close(sockfd)) < 0)  
  118. #else  
  119.     if((ret = closesocket(sockfd)) < 0)  
  120. #endif  
  121.     {  
  122.         fprintf(stderr, "op_close error/n");  
  123.         exit(EXIT_FAILURE);  
  124.     }  
  125.     return ret;  
  126. }  
  127. // 打开文件  
  128. FILE* op_fopen(const char *path, const char *mode)  
  129. {  
  130.     FILE *fp = fopen(path, mode);  
  131.     if (NULL == fp)  
  132.     {  
  133.         printf("File:/t%s Can Not Open To Write/n", path);  
  134.         exit(EXIT_FAILURE);  
  135.     }  
  136.     return fp;  
  137. }  
  138. // 关闭文件指针  
  139. int op_fclose(FILE *stream)  
  140. {  
  141.     int ret;  
  142.     if ((ret = fclose(stream)) < 0)  
  143.     {  
  144.         fprintf(stderr, "op_fclose error/n");  
  145.         exit(EXIT_FAILURE);  
  146.     }  
  147.     return ret;  
  148. }  
  149. // 休眠函数,对于usleep为微秒级别,对于Sleep为毫秒级别  
  150. void op_sleep(int micro_seconds)  
  151. {  
  152. #ifndef WIN32  
  153.     usleep(micro_seconds);  
  154. #else  
  155.     Sleep(micro_seconds);  
  156. #endif  
  157. }  
  158. // 字符串比较函数  
  159. int op_stricmp(char *s1,char * s2)  
  160. {  
  161. #ifndef WIN32  
  162.     return strcasecmp(s1, s2);  
  163. #else  
  164.     return stricmp(s1, s2);  
  165. #endif  
  166. }  

六、完成了上述的操作之后,就可以分别对client和server端进行编译了,先启动server端服务器,然后用命令行的形式运行client端,就可以成功了吧。哈哈!我们来看一下使用protobuf进行socket通信的实际效果!给大家截个图!

 

 

 

最近项目紧,没空时间来好好写博客,只能粗略记录一下,等实习结束后,要把这段时间的所学所感好好总结下来。

顺便说一下,op_socket这个SOCKET是跨平台的,写个makefile可以直接在UNIX环境下运行的,咳咳,写的太龊了大家见笑了。。。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462302.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14 Scroll 滚动搜索

Scroll的用法&#xff1a;第一次搜的时候&#xff0c;要指定 快照保留时间1min&#xff0c;分页的大小&#xff1a;2条/页&#xff1b;对于第一次搜索&#xff0c;ES会返回一个这个scroll的id&#xff1b;下次再搜的时候&#xff0c;就带着这个scrollid去搜就行了&#xff0c;不…

VS2008中使用JSONCPP方法小结

http://sourceforge.net/projects/jsoncpp/?sourcetyp_redirect C要使用JSON来解析数据&#xff0c;一般采用jsoncpp. 下载jsoncpp后&#xff0c;按ReadMe文档的说法是要先安装的&#xff0c;但是安装比较麻烦。然而事实上&#xff0c;我们并不需要安装&#xff0c;就可以直接…

如何在Windows下编译OpenSSL

OpenSSL是一个开源的第三方库&#xff0c;它实现了SSL&#xff08;Secure SocketLayer&#xff09;和TLS&#xff08;Transport Layer Security&#xff09;协议&#xff0c;被广泛企业应用所采用。对于一般的开发人员而言&#xff0c;在 http://slproweb.com/products/Win32Op…

《团队名称》第八次团队作业:Alpha冲刺day5

项目内容这个作业属于哪个课程2016计算机科学与工程学院软件工程(西北师范大学)这个作业的要求在哪里实验十二 团队作业8—软件测试与ALPHA冲刺团队名称快活帮作业学习目标 &#xff08;1&#xff09;掌握软件测试基础技术。 &#xff08;2&#xff09;学习迭代式增量软件开发过…

(转)C# 把我所积累的类库全部分享给博友(附件已经上传)

http://files.cnblogs.com/LsGW/Common.zip转载于:https://www.cnblogs.com/meetrice/archive/2012/01/02/2310428.html

前端的小图标获取

搜索iconfont&#xff0c;里面有很多图标&#xff0c;鼠标移到想要的图标上&#xff0c;然后点击一个类似购物车的图标&#xff0c;然后添加到项目&#xff0c;下载到本地&#xff0c;有一个使用指南的html&#xff0c;然后参照上面的改就好。 把下载好的.css和.eot文件拖到css…

$JavaScript(3)

41、渐进增强和优雅降级 渐进增强 &#xff1a;针对低版本浏览器进行构建页面&#xff0c;保证最基本的功能&#xff0c;然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。 优雅降级 &#xff1a;一开始就构建完整的功能&#xff0c;然后再针对低版本浏…

转:Yupoo(又拍网)的系统架构

Yupoo!&#xff08;又拍网&#xff09; 是目前国内最大的图片服务提供商&#xff0c;整个网站构建于大量的开源软件之上。以下为其使用到的开源软件信息&#xff1a; 操作系统&#xff1a;CentOS、MacOSX、Ubuntu 服务器&#xff1a;Apache、Nginx、Squid 数据库&#xff1a;…

浏览器搜索功能的使用

浏览器搜索功能的使用 直接在地址栏中搜索你需要的内容 用浏览器的搜索栏进行搜索 用双引号 " " 进行搜索 转载于:https://www.cnblogs.com/GaoNa/p/11061066.html

有趣的反直觉的“三门问题”

————— 第二天 ————— ———————————— 如何进行分析呢&#xff1f;我们不妨回到问题的起点&#xff0c;也就是参与者即将进行初次选择&#xff0c;主持人还没有打开一扇空门的时候。 从上图可以看出&#xff0c;我们总共面临着6种不同的子局面。这些子局面的…

转使用Moq让单元测试变得更简单

【ASP.Net MVC3 】使用Moq让单元测试变得更简单 前几天调查完了unity。现在给我的任务是让我调查Moq。 以下是自己找了资料&#xff0c;总结并实践的内容。如果有表述和理解错误的地方。恳请指正。 什么是Moq&#xff1f; Moq&#xff08;英语发音是Mock-you 或者只是mock&…

Web Service实现分布式服务的基本原理

简单的说&#xff0c; 就是客户端根据WSDL 生成 SOAP 的请求消息&#xff0c; 通过 HTTP 传输方式&#xff08;也可以是其它传输方式&#xff0c; 如 FTP 或STMP 等&#xff0c;目前 HTTP 传输方式已经成为 J2EE Web Service 的标准&#xff09;传给对方&#xff0c; 服务方实现…

使用docker部署mysql主从复制集群

一、环境搭建 虚拟机环境&#xff1a;centos7 IP:192.168.37.134 用户名&#xff1a;root 密码&#xff1a;123 启动3个容器&#xff0c;一个是master&#xff0c;端口是3307&#xff0c;另外两个是slaver&#xff0c;端口是3308和3309 docker pull mysql:5.7docker run -p …

特殊的质数肋骨

特殊的质数肋骨 时间限制: 0 Sec 内存限制: 128 MB题目描述 农民约翰的母牛总是生产出最好的肋骨。你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质…

学滑冰

为什么80%的码农都做不了架构师&#xff1f;>>> http://www.cnr.cn/wcm/zhuanti/harb/bxyd/t20041230_163420.html 学滑冰&#xff08;一&#xff09; 到冰场上穿冰刀奔驰豪情一番&#xff0c;真是今人激情万千&#xff0c;你会滑冰吗&#xff1f;如果你还不会滑冰…

Java-Redis 热部署问题

项目请求时报错&#xff1a;java.lang.ClassCastException: cn.xingaohbd.seckil.model.User cannot be cast to cn.xingaohbd.seckil.model.User at cn.xingaohbd.seckil.service.impl.UserServiceImpl.getUser(UserServiceImpl.java:33) ~[classes/:na] at cn.xingaohbd.seck…

vs2013编译boost1.55.0 32/64位

在使用vs2013编译boost-1.55.0之前&#xff0c;先要给boost做下修改&#xff1a; boost_1_55_0\boost\intrusive\detail\has_member_function_callable_with.hpp line:222 template<class U> static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION…

ICE简单介绍及使用示例

1、ICE是什么&#xff1f; ICE是ZEROC的开源通信协议产品&#xff0c;它的全称是&#xff1a;The Internet Communications Engine&#xff0c;翻译为中文是互联网通信引擎&#xff0c;是一个面向对象的中间件&#xff0c;使我们能够以最小的代价构建分布式应用程序。ICE使我们…

AtCoder Grand Contest 017

AtCoder Grand Contest 017 A - Biscuits 有\(n\)个数&#xff0c;问有多少个集合的数的和模\(2\)余\(P\)。 随便\(dp\)一下就好了。 #include<iostream> #include<cstdio> using namespace std; #define ll long long inline int read() {int x0;bool tfalse;char…

CentOS 6.2 安装教程

一、CentOS简介 CentOS是Linux的发行版之一&#xff0c;它安全、稳定、高效&#xff0c;是我最喜欢的Linux发行版之一。CentOS根据Red Hat Enterprise Linux开放源代码编译而成&#xff0c;与RedHat Linux并没有什么本质上的差别。但Red Hat Enterprise Linux是商业软件&#x…