send和sendmsg性能测试
1,摘要:测试send和sendmsg的性能,影响这两个函数性能主要有发送的字节大小,增加循环次数,从100到10000000(千万)
2,基本信息
cat /proc/cpuinfo查看CPU信息,如下:
Intel(R) Xeon(R) CPU E5-2698 v3 @ 2.30GHz
cat /proc/version 查看操作系统内核版本,如下:
Linux version 3.10.0-327.el7.x86_64
cat /proc/meminfo查看内存信息,如下:
MemTotal: 131748016 kB
MemFree: 42526620 kB
MemAvailable: 60623924 kB
3,send性能测试
服务器端 : nc -lu 8888
客服端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={,,,,,,,,,,};
int bufsizeSet[]={,,,,,,}; int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,)) == -);
//printf("We get the sockfd~\n");
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons();
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
bzero(&(their_addr.sin_zero), ); while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -);
// printf("Get the Server~Cheers!\n"); 濉濞绔俊姣
// numbytes = recv(sockfd, buf, BUFSIZ,0);//妤娑?
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=;
for(buf_i=;buf_i<;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=;
for(i=;i<buf_len;i++)
{
buf[i]='a' + rand()%;
}
buf[buf_len]='\0';
int recycle_i=;
for(recycle_i=;recycle_i<;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=;i<recycle_times;i++)
{ numbytes = send(sockfd, buf, strlen(buf), );
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.2,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return ;
}
4,sendmsg性能测试(iovlen=1)
服务器端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
/************************************************************************************************************************ *************************************************************************************************************************/
int main(int argc, char *argv[])
{
int fd, new_fd, struct_len, numbytes,i;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buff[BUFSIZ];
//struct msghdr msg;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = INADDR_ANY;
// bzero(&(server_addr.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);
while((fd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
if (bind(fd, (struct sockaddr*)(&server_addr), struct_len) < 0)
{
fprintf(stderr, "bind fail\n");
exit(EXIT_FAILURE);
}
printf("Bind Success!\n");
// fd = socket(AF_INET, SOCK_DGRAM, 0);
/*while(bind(fd, (struct sockaddr *)&server_addr, struct_len) == -1);
printf("Bind Success!\n");
while(listen(fd, 100) == -1);
printf("Listening....\n");
printf("Ready for Accept,Waitting...\n");
new_fd = accept(fd, (struct sockaddr *)&client_addr, &struct_len);
*/
//printf("Get the Client.\n");
// numbytes = send(new_fd,"Welcome to my server\n",21,0);
while(1)
{
printf("recemsg\n");
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
msg.msg_name =&client_addr;
msg.msg_namelen =sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base =buff;
io.iov_len =BUFSIZ;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
numbytes = recvmsg(fd,&msg,0);
char * temp = msg.msg_iov[0].iov_base;//获取得到的数据
temp[numbytes] = '\0';//为数据末尾添加结束符
// printf("get %d message:%s", numbytes,temp);
printf("get %d \n", numbytes);
}
// close(new_fd);
close(fd);
return 0;
}
客服端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={100,500,1000,5000,10000,50000,100000,500000,1000000,5000000,10000000};
int bufsizeSet[]={128,256,512,1024,2048,3072,4096}; int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
//printf("We get the sockfd~\n");
bzero(&their_addr, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(8888);
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
//their_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//bzero(&(their_addr.sin_zero), 8); // while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
// printf("Get the Server~Cheers!\n");
// numbytes = recv(sockfd, buf, BUFSIZ,0);//接收服务器端信息
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=0;
for(buf_i=0;buf_i<7;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=0;
for(i=0;i<buf_len;i++)
{
buf[i]='a' + rand()%26;
}
buf[buf_len]='\0';
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
//msg.msg_name = NULL;
msg.msg_name = &their_addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base = buf;
io.iov_len = buf_len;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
int recycle_i=0;
for(recycle_i=0;recycle_i<11;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=0;i<recycle_times;i++)
{ //numbytes = send(sockfd, buf, strlen(buf), 0);
numbytes = sendmsg(sockfd, &msg, 0);
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.2,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return 0;
}
4,sendmsg性能测试(iovlen=4)
服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<time.h>
#include <sys/times.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//#define BUFSIZ 1024
#define recycle 1000000
static inline uint64_t rte_rdtsc(void)
{
union {
uint64_t tsc_64;
struct {
uint32_t lo_32;
uint32_t hi_32;
};
}tsc;
asm volatile("rdtsc":
"=a" (tsc.lo_32),
"=d" (tsc.hi_32)); return tsc.tsc_64;
}
int recycleSet[]={100,500,1000,5000,10000,50000,100000,500000,1000000,5000000,10000000};
int bufsizeSet[]={128,256,512,1024,2048,3072,4096,5120,6144,7168,8192,9216,15000,150000};
#define BUF_CNT 14
int main(int argc,char *argv[])
{
/*if(argc<3)
{
printf("paramaters error! ./socet_sendmsg 1000 1024");
return -1;
}
int recycle_times=atoi(argv[1]);
int buf_len=atoi(argv[2]);
*/
int sockfd,numbytes;
//char buf[BUFSIZ]; int sc_clk_tck;
sc_clk_tck = sysconf(_SC_CLK_TCK);
struct sockaddr_in their_addr;
//printf("break! sc_clk_tck=%d\n",sc_clk_tck);
while((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
//printf("We get the sockfd~\n");
bzero(&their_addr, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(9999);
their_addr.sin_addr.s_addr=inet_addr("192.168.10.8");
//their_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//bzero(&(their_addr.sin_zero), 8); // while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
// printf("Get the Server~Cheers!\n");
// numbytes = recv(sockfd, buf, BUFSIZ,0);//接收服务器端信息
// buf[numbytes]='\0';
// printf("%s",buf); //clock_t start_time,end_time;
// start_time=clock();
int buf_i=0;
for(buf_i=0;buf_i<14;buf_i++){
int buf_len=bufsizeSet[buf_i];
char *buf=(char *)calloc(buf_len,sizeof(char));
int i=0;
for(i=0;i<buf_len;i++)
{
buf[i]='a' + rand()%26;
}
buf[buf_len]='\0';
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
//msg.msg_name = NULL;
msg.msg_name = &their_addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
struct iovec io[4];
io[0].iov_base = buf;
io[0].iov_len = buf_len;
io[1].iov_base = buf;
io[1].iov_len = buf_len;
io[2].iov_base = buf;
io[2].iov_len = buf_len;
io[3].iov_base = buf;
io[3].iov_len = buf_len; msg.msg_iov = io;
msg.msg_iovlen =4;
int recycle_i=0;
for(recycle_i=8;recycle_i<9;recycle_i++){
int recycle_times=recycleSet[recycle_i];
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
for(i=0;i<recycle_times;i++)
{ //numbytes = send(sockfd, buf, strlen(buf), 0);MSG_DONTWAIT
numbytes = sendmsg(sockfd, &msg, 0);
//numbytes=recv(sockfd,buf,BUFSIZ,0);
//buf[numbytes]='\0';
//printf("send:%d\n",numbytes);
}
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
//printf("recycle_times=%d duration=%f numbytes=%d duration_rte=%f\n",recycle_times,duration_time,numbytes,duration/2.2);
printf("%d,%d,%d, %f ,%f,%f\n",recycle_times,numbytes,buf_len,duration_time,duration/2.3,duration_time*1.0/recycle_times);
}
}
close(sockfd);
return 0;
}
客户端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
/************************************************************************************************************************
1、int socket(int family,int type,int protocol)
family:
指定使用的协议簇:AF_INET(IPv4) AF_INET6(IPv6) AF_LOCAL(UNIX协议) AF_ROUTE(路由套接字) AF_KEY(秘钥套接字)
type:
指定使用的套接字的类型:SOCK_STREAM(字节流套接字) SOCK_DGRAM
protocol:
如果套接字类型不是原始套接字,那么这个参数就为0
2、int bind(int sockfd, struct sockaddr *myaddr, int addrlen)
sockfd:
socket函数返回的套接字描述符
myaddr:
是指向本地IP地址的结构体指针
myaddrlen:
结构长度
struct sockaddr{
unsigned short sa_family; //通信协议类型族AF_xx
char sa_data[14]; //14字节协议地址,包含该socket的IP地址和端口号
};
struct sockaddr_in{
short int sin_family; //通信协议类型族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //IP地址
unsigned char si_zero[8]; //填充0以保持与sockaddr结构的长度相同
};
3、int connect(int sockfd,const struct sockaddr *serv_addr,socklen_t addrlen)
sockfd:
socket函数返回套接字描述符
serv_addr:
服务器IP地址结构指针
addrlen:
结构体指针的长度
4、int listen(int sockfd, int backlog)
sockfd:
socket函数绑定bind后套接字描述符
backlog:
设置可连接客户端的最大连接个数,当有多个客户端向服务器请求时,收到此值的影响。默认值20
5、int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen)
sockfd:
socket函数经过listen后套接字描述符
cliaddr:
客户端套接字接口地址结构
addrlen:
客户端地址结构长度
6、int send(int sockfd, const void *msg,int len,int flags)
7、int recv(int sockfd, void *buf,int len,unsigned int flags)
sockfd:
socket函数的套接字描述符
msg:
发送数据的指针
buf:
存放接收数据的缓冲区
len:
数据的长度,把flags设置为0
*************************************************************************************************************************/
int main(int argc, char *argv[])
{
int fd, new_fd, struct_len, numbytes,i;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char buff[BUFSIZ*10];
printf("BUFFSIZE %d\n",BUFSIZ);
//struct msghdr msg;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9999);
server_addr.sin_addr.s_addr = INADDR_ANY;
// bzero(&(server_addr.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);
while((fd = socket(AF_INET,SOCK_DGRAM,0)) == -1);
if (bind(fd, (struct sockaddr*)(&server_addr), struct_len) < 0)
{
printf("bind error\n");
return -1;
}
printf("Bind Success!\n");
// fd = socket(AF_INET, SOCK_DGRAM, 0);
/*while(bind(fd, (struct sockaddr *)&server_addr, struct_len) == -1);
printf("Bind Success!\n");
while(listen(fd, 100) == -1);
printf("Listening....\n");
printf("Ready for Accept,Waitting...\n");
new_fd = accept(fd, (struct sockaddr *)&client_addr, &struct_len);
*/
//printf("Get the Client.\n");
// numbytes = send(new_fd,"Welcome to my server\n",21,0);
int cnt=0;
while(1)
{
printf("recemsg\n");
struct msghdr msg;
bzero(&msg,sizeof(struct msghdr));
msg.msg_name =&client_addr;
msg.msg_namelen =sizeof(struct sockaddr_in);
struct iovec io;
io.iov_base =buff;
io.iov_len =BUFSIZ*100;
msg.msg_iov = &io;
msg.msg_iovlen = 5;
numbytes = recvmsg(fd,&msg,0);
char * temp = msg.msg_iov[0].iov_base;//获取得到的数据
temp[numbytes] = '\0';//为数据末尾添加结束符
// printf("get %d message:%s", numbytes,temp);
if(numbytes>0)
cnt++;
printf("get %d cnt %d\n", numbytes,cnt);
}
// close(new_fd);
close(fd);
return 0;
}
6,send测试数据表
7,sendmsg测试数据表(iovlen=1)
7,sendmsg测试数据表(iovlen=4)
8,比较send,sendmsg(iovlen=1),sendmsg(iovlen=4)
9,用gettimeofday测试性能基本逻辑(gettimeofday和滴答数转化成时间基本差不多)
单位为:微秒
struct timeval start_time,end_time;
gettimeofday(&start_time,NULL);
uint64_t start=rte_rdtsc();
函数调用
uint64_t end=rte_rdtsc();
//end_time=clock();
gettimeofday(&end_time,NULL);
uint64_t duration=end-start;
double duration_time=1000000*(end_time.tv_sec-start_time.tv_sec)+(end_time.tv_usec-start_time.tv_usec);
8,send和sendmsg性能测试比较(循环一千万次,算出一次时间开销(微秒))
结论:
1,send和sendmsg的性能基本一样
2,性能随字节成正比,比如128B~1.55微秒 ,256B~2.57微秒,1024B~8.72微秒,4096B~34.22微秒
3,sendmsg(iovlen=1)和sendmsg(iovlen=4)的在发送相同字节情况下,性能也是4倍,sendmsg在性能上并没得到优化
send和sendmsg性能测试的更多相关文章
- send和sendmsg性能测试【sendmsg和send的性能基本一样,并没有得到优化】
1,摘要:测试send和sendmsg的性能,影响这两个函数性能的因素主要有发送的字节大小,增加循环次数,从100到10000000(千万)减少计算误差 2,基本信息cat /proc/cpuinfo ...
- send, sendto, sendmsg - 从套接字发送消息
概述 #include <sys/types.h> #include <sys/socket.h> int send(int s, const void *msg, size_ ...
- Man——send(2)翻译
##纯手打 Man——send(2) -->NAME: send, sendto, sendmsg - 在socket上发送一条消息 -->总览: #include <sys/typ ...
- 一文彻底搞通TCP之send & recv原理
接触过网络开发的人,大抵都知道,上层应用使用send函数发送数据,使用recv来接收数据,而send和recv的实现原理又是怎样的呢? 在前面的几篇文章中,我们有提过,TCP是个可靠的.全双工协议.其 ...
- jee websocket搭建总结
1.使用框架spring+springmvc+mybatis+jdk7+tomcat7+maven 2.基本原理: a. WebSocket协议是一种双向通信协议,它建立在TCP之上,同http一样通 ...
- javaScript AJAX
AJAX的实现 var sAjax = function () { var sendMsg = { url: "", sendType: "POST", Con ...
- Socket网络编程-基础篇
Socket网络编程 网络通讯三要素: IP地址[主机名] 网络中设备的标识 本地回环地址:127.0.0.1 主机名:localhost 端口号 用于标识进程的逻辑地址 有效端口:0~65535 其 ...
- (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- [16]APUE:套接字
[a] socket / socketpair #include <sys/socket.h> int socket(int domain, int type, int protocol) ...
随机推荐
- css实现气泡框效果
前提:气泡框或者提示框是网页很常见的,实现它的方式有很多,我们以前最常用的就是切图片 然后通过 "定位" 方式 定位到相应的位置,但是用这种方式维护很麻烦,比如设计师想改成另外一种 ...
- P3084 [USACO13OPEN]照片Photo
题目描述 农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N. 于是约翰拍摄了M(1 <= M <= 100,00 ...
- Android应用安全之脆弱的加密
程序员希望通过加密来提升程序的安全性性,但却缺乏专业的密码学背景知识,使得应用对数据的保护非常薄弱.本文将介绍可能出现在Android应用中的一些脆弱的加密方式,以及对应的攻击方法. 造成脆弱加密的主 ...
- 20155213免考项目——简易的HIDAttack
20155213免考项目--简易的HIDAttack 听5214说他做不出来自己的免考项目,于是就转向bof进阶,并且成功做出了64位的ROP攻击...... 既然如此,那我就再做一个吧,但都已经期末 ...
- mfc CFileDialog类
知识点: CFileDialog类 SetBitmap LoadImage 动态显示图片 一.CFileDialog类 构造函数 CFileDialog( BOOL bOpenFileDialog, ...
- JSON传输数组的基本操作
目标JSON结果如下: 生成JSON的的过程如下: Document document; Document::AllocatorType& allocator = document.GetAl ...
- libgdx相关知识点
Gdx.graphics.setContinuousRendering(false); 设置图像为非连续自动渲染. 设置Opengl的混合模式,支持alpha属性 Gdx.gl.glBlendFunc ...
- [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
- 设计模式 笔记 迭代器模式 Iterator
//---------------------------15/04/26---------------------------- //Iterator 迭代器模式----对象行为型模式 /* 1:意 ...
- c++ Arx二次开发创建椭圆和样条曲线
一.本节课程 c++ Arx二次开发创建椭圆和样条曲线 二.本节要讲解的知识点 1.如何应用C++ ARX二次开发创建椭圆(对AcDbEllipse类的构造函数的直接封装和根据外接矩形来创建椭圆) 2 ...