ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:34.02KB ,
资源ID:8657969      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8657969.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Linux下消息队列和socket绝对速度比拼[转].docx)为本站上传会员【s4****5z】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Linux下消息队列和socket绝对速度比拼[转].docx

1、在当今的网络时代,我们常常见到的进程间通信方式都是socket,比如Java的EJB调用,Java和C通信,Web Service服务等。socket是最常用的通讯技术,几乎所有的系统、语言都支持,socket也是面向网络的,通信的两方可以跨越IP网络进行传输。 在本地通信中(同一台机器上的进程间通讯),socket的网络特性却成了累赘,组装解析网络报头、报文确认、CRC校验等都是针对网络的,本地通信没有必要,反而会影响传输效率。本地通信的一些传统技术,如管道、FIFO、消息队列等,没有网络功能的负担,传输速度应该高于socket,那到底高多少以至于值得在应用中替换socket技术呢,今天就

2、来一场小测试,就System V消息队列和socket之间,做一次全面的速度比拼。 比拼场地 本人的笔记本:赛扬1.5G 内存1.5G 系统:Ubuntu8.04 Desktop (Linux 2.6.24-24-generic) JDK:1.6 第一回合: Java测试 先说明一下,Java并不支持System V消息队列,因此特为Java提供了JNI接口,我们使用lajp_9.09提供C源码编译的so动态连接库,lajp的下载地址和文档: 首先上场的是System V消息队列。 发送端程序: package test;   import lajp.MsgQ;  

3、public class TestSend {     /** 消息队列KEY */     static final int IPC_KEY = 0×20021230;       static     {        //JNI        System.loadLibrary("lajpmsgq");     }       public static void main(String[] args)     {         //创建或获得现有的消息队列         int msqid = MsgQ.msgget(IPC_KEY);      

4、  //发送字节数组         byte[] msg = new byte[1024];               for (int i = 0; i < 1024 * 5000; i++)         {             //每次发送1204字节到消息队列,9527是消息类型             MsgQ.msgsnd(msqid, 9527, msg, msg.length);         }         System.out.println("发送结束.");     } } 接收端程序: package test;  

5、 import lajp.MsgQ;   public class TestRcv {     /** 消息队列KEY */     static final int IPC_KEY = 0×20021230;       static     {         //JNI         System.loadLibrary("lajpmsgq");     }       public static void main(String[] args)     {         //创建或获得现有的消息队列         int msqid = MsgQ.

6、msgget(IPC_KEY);         //接收缓冲区         byte[] msg = new byte[1024];                 long start = System.currentTimeMillis(); //开始时间                 for (int i = 0; i < 1024 * 5000; i++)         {             //每次从消息队列中接收消息类型为9527的消息,接收1204字节             MsgQ.msgrcv(msqid, msg, msg.length,

7、 9527);         }           long end = System.currentTimeMillis(); //结束时间         System.out.println("用时:" + (end – start) + "毫秒");     } } 程序很简单,需要说明的是三个JNI方法调用: msgget()方法: System V消息队列的技术要求,含义是通过一个指定的KEY获得消息队列标识符。 msgsnd()方法: 发送。 msgrcv()方法: 接收。 发送方进行了(1024 * 5000)次发送,每次发送1024字节数据,接收方

8、进行了(1024 * 5000)次接收,每次接收1024字节,共计发送接收5G数据。测试时先启动TestSend程序,再启动TestRcv程序,共进行5轮次测试,测试结果如下: 用时:29846毫秒 用时:29591毫秒 用时:29935毫秒 用时:29730毫秒 用时:29468毫秒 平均速度:29714毫秒 用top命令监控测试期间的CPU、内存的使用: 接下来上场的是socket。 发送端程序: import java.io.IOException; import java.io.OutputStream; import .Socket;     publ

9、ic class SocketSend {     public static void main(String[] args) throws IOException     {         //Socket         Socket socket = new Socket("127.0.0.1", 9527);         //输出流         OutputStream out = socket.getOutputStream();         //发送字节数组         byte[] msg = new byte[1024];      

10、      long start = System.currentTimeMillis(); //开始时间                 for (int i = 0; i < 1024 * 5000; i++)         {             //发送             out.write(msg);         }             long end = System.currentTimeMillis(); //结束时间         System.out.println("用时:" + (end – start) + "毫秒");  

11、   } } 接收端程序: import java.io.IOException; import java.io.InputStream; import .ServerSocket; import .Socket;   public class SocketRecv {     public static void main(String[] args) throws IOException     {         //侦听9527端口         ServerSocket serverSocket = new ServerSocket(9527);    

12、     //Socket         Socket socket = serverSocket.accept();         //输入流         InputStream in = socket.getInputStream();         //接收缓冲区         byte[] msg = new byte[1024];                     for (int i = 0; i < 1024 * 5000; i++)         {             //每次接收1204字节             in.read

13、msg);         }                     System.out.println("接受结束.");     } }   程序同样很简单,同样发送接收了(1024 * 5000)次,同样5G数据,socket程序必须先启动服务方SocketRecv,然后启动客户方SocketSend,共进行5轮次测试,测试结果如下: 用时:33951毫秒 用时:33448毫秒 用时:33987毫秒 用时:34638毫秒 用时:33957毫秒 平均速度:33996.2毫秒 用top命令监控测试期间的CPU、内存的使用: 测试结果让人对消息队列有点失望

14、性能优势微弱大约只领先了13%,且程序复杂性要大的多(使用了JNI)。不过重新审视测试过程有一个疑问:消息队列程序调用了自定义的JNI接口,而socket是Java内嵌的功能,是否JVM对 socket有特殊的优化呢? 怀着这个疑问,进行第二场纯C程序的测试。 第二回合: C程序测试 首先上场的还是System V消息队列。 发送端程序: #include #include #include     #define IPC_KEY 0×20021230  /* 消息队列KEY */     /*消息

15、结构*/ struct message {     long msg_type;            /* 消息标识符 */     char msg_text[1024];    /* 消息内容 */ };     int main() {     /* 创建或获得现有的消息队列 */     int msqid = msgget(IPC_KEY, IPC_CREAT | 0666);     /* 消息结构 */     struct message msgq;     msgq.msg_type = 9527; /* 消息类型 */        

16、     int i;     for (i = 0; i < 1024 * 5000; i++)     {           /* 接收 */         msgsnd(msqid, &msgq, 1024, 0);     }         printf("msgq发送结束,共发送%d次n", i);     return 0; } 接收端程序: #include #include #include     #define IPC_KEY 0×20021230  /* 消息队

17、列KEY */     /*消息结构*/ struct message {     long msg_type;            /* 消息标识符 */     char msg_text[1024];    /* 消息内容 */ };     int main() {     /* 创建或获得现有的消息队列 */     int msqid = msgget(IPC_KEY, IPC_CREAT | 0666);     /* 消息结构 */     struct message msgq;             int i;     for

18、 (i = 0; i < 1024 * 5000; i++)     {           /* 接收 */         msgrcv(msqid, &msgq, 1024, 9527, 0);     }         printf("msgq接收结束,共接收%d次n", i);     return 0; } 和第一场一样,发送接收了(1024 * 5000)次,同样5G数据,先启动接收端程序msgrecv,然后以$time msgsend方式启动客户端程序,共进行5轮次测试,time的测试结果如下: 用户 系统 时钟 第一次: 0.992s 7.084s

19、18.202s 第二次: 0.888s 7.280s 18.815s 第三次: 1.060s 7.656s 19.476s 第四次: 1.048s 7.124s 20.293s 第五次: 1.008s 7.160s 18.655s 用top命令监控测试期间的CPU、内存的使用: 接下来上场的是socket。 发送端程序: #include #include #include   char msg[1024]; /* 发送消息 */     int main() {     char *ip = "

20、127.0.0.1";     /* 发送地址 */     int port = 9527;             /* 发送端口 */         struct hostent *server_host = gethostbyname(ip);         /* 客户端填充 sockaddr 结构 */     struct sockaddr_in client_addr;             /* 客户端地址结构 */     bzero(&client_addr, sizeof(client_addr));     client_addr.sin_fami

21、ly = AF_INET;             /* AF_INET:IPV4协议 */     client_addr.sin_addr.s_addr = ((struct in_addr *)(server_host->h_addr))->s_addr; /* 服务端地址 */     client_addr.sin_port = htons(port);         /* 端口 */             /* 建立socket */     int sockfd = socket(AF_INET, SOCK_STREAM, 0);     /* 连接 */  

22、  connect(sockfd, (struct sockaddr *)(&client_addr), sizeof(client_addr));                 int i;     for (i = 0; i < 1024 * 5000; i++)     {           /* 发送 */         send(sockfd, msg, 1024, 0);     }         printf("发送结束,共发送%d次n", i);       return 0; } 接收端程序: #include #

23、include #include     char msg[1024]; /* 接收缓冲区 */     int main() {     int listen_port = 9527;                         /* 侦听端口 */       int listenfd = socket(AF_INET, SOCK_STREAM, 0); /* 建立侦听socket */         /* 服务端填充 sockaddr 结构 */     struct sockaddr_in server_addr;

24、                     /* 服务端地址结构 */     bzero(&server_addr, sizeof(server_addr));     server_addr.sin_family = AF_INET;                     /* AF_INET:IPV4协议 */     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);     /* INADDR_ANY:通配地址,表示内核选择IP地址 */     server_addr.sin_port = htons(listen_port);

25、             /* 端口 */             /* 绑定端口 */     bind(listenfd, (struct sockaddr *)(&server_addr), sizeof(server_addr));     /* 侦听 */     listen(listenfd, 5);     int sockfd = accept(listenfd, NULL, NULL);             int i;     for (i = 0; i < 1024 * 5000; i++)     {           /* 接收 */

26、         recv(sockfd, msg, 1024, 0);     }         printf("接收结束,共接收%d次n", i);       return 0; } C语言中,socket程序复杂了不少。测试标准和Java相同,发送接收了(1024 * 5000)次,5G数据,先启动接收端程序,然后以time方式启动发送端,测试结果如下: 用户 系统 时钟 第一次: 0.524s 9.765s 20.666s 第二次: 0.492s 9.825s 20.530s 第三次: 0.468s 9.493s 21.831s 第四次: 0.512s 9.

27、205s 20.059s 第五次: 0.440s 9.605s 21.888s 用top命令监控测试期间的CPU、内存的使用: C语言的socket程序系统用时多一些,消息队列程序用户用时多一些,这和他们的实现方式相关,从时钟比较看,消息队列比socket快10%左右,和Java测试结果相似。比较Java和C,C只领先了三分之一,看来当前的Java效率已经相当高了。 还不能忙于下结论,socket的通信方式一般有两种:长连接和短连接。长连接指发送端和接收端建立连接后,可以保持socket通道进行多次消息传输,在这种场景基本不用计算socket建立和关闭的时间,前面的测试都是基于长连

28、接方式;短连接一般在建立socket通道后,只进行一次通信,然后就关闭 socket通道,这种场景必须考虑socket建立和关闭的时间(socket建立连接需要三次握手,关闭连接要四次通信)。 第三回合: Java测试(短连接) 将第一回合中的Java程序稍作修改,先看socket的: 发送端程序: import java.io.IOException; import java.io.OutputStream; import .Socket;   public class SocketSend2 {     public static void main(String[]

29、args) throws IOException     {         long start = System.currentTimeMillis(); //开始时间         //发送字节数组         byte[] msg = new byte[1024];           for (int i = 0; i < 1024 * 1000; i++)         {             //建立Socket连接             Socket socket = new Socket("127.0.0.1", 9527);        

30、     //输出流             OutputStream out = socket.getOutputStream();             //发送             out.write(msg);                         //关闭输出流             out.close();             //关闭socket连接             socket.close();         }           long end = System.currentTimeMillis(); //结束时

31、间         System.out.println("用时:" + (end – start) + "毫秒");     } } 建立socket的语句放在了循环内部,这样每次发送都是新建的连接,025行的关闭语句是必须的,因为socket是系统的有限资源,支持不了这么大规模的申请。 接收端程序: import java.io.IOException; import java.io.InputStream; import .ServerSocket; import .Socket;   public class SocketRecv2 {     public

32、static void main(String[] args) throws IOException     {         //侦听9527端口         ServerSocket serverSocket = new ServerSocket(9527);           //接收缓冲区         byte[] msg = new byte[1024];                       for (int i = 0; i < 1024 * 1000; i++)         {             //接到客户端Socket连接请

33、求             Socket socket = serverSocket.accept();             //输入流             InputStream in = socket.getInputStream();             //每次接收1204字节             in.read(msg);                             //关闭输入流             in.close();             //关闭socket连接             socket.close();

34、        }                     System.out.println("接受结束.");     } } 接收端也做了相应的改动,发送和接收次数降低到(1024 * 1000)次,测试结果:431280毫秒,不要吃惊,没错是431.280秒,这也是书本上为什么总在强调使用数据库连接池的原因。 消息队列没有像socket那样的连接概念,为了做个参考,将第一回合中的消息队列程序也修改一下: 发送端程序: package test;   import lajp.MsgQ;   public class TestSend2 {     /** 消

35、息队列KEY */     static final int IPC_KEY = 0×20021230;       static     {         //JNI         System.loadLibrary("lajpmsgq");     }         public static void main(String[] args)     {         //发送字节数组         byte[] msg = new byte[1024];           for (int i = 0; i < 1024 * 1000; i++)

36、         {             //创建或获得现有的消息队列             int msqid = MsgQ.msgget(IPC_KEY);                         //每次发送1204字节             MsgQ.msgsnd(msqid, 9527, msg, msg.length);         }             System.out.println("发送结束.");     } } 将024行的msgget()方法放在循环内部,作为和socket比较的“连接”。 接收段程序: pa

37、ckage test;   import lajp.MsgQ;     public class TestRcv2 {     /** 消息队列KEY */     static final int IPC_KEY = 0×20021230;         static     {         //JNI         System.loadLibrary("lajpmsgq");     }       public static void main(String[] args)     {         long start = System.c

38、urrentTimeMillis(); //开始时间         //接收缓冲区         byte[] msg = new byte[1024];                 for (int i = 0; i < 1024 * 1000; i++)         {             //创建或获得现有的消息队列             int msqid = MsgQ.msgget(IPC_KEY);                         //每次接收1204字节             MsgQ.msgrcv(msqid, msg, msg.length, 9527);         }           long end = System.currentTimeMillis(); //结束时间         System.out.println("用时:" + (end – start) + "毫秒");     } } 测试结果:6617毫秒。 总结: 在能够使用socket长连接的应用中,建议使用socket技术,毕竟很通用熟悉的人也多,而消息队列能够提高的效率有限;在只能使用socket短连接的应用中,特别是并发量大的场景,强烈建议使用消息队列,因为能够极大的提高通信速率。

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服