已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
技术分析:基本 UDP 套接字编程UDP 协议和 TCP 协议不同,它是一种面向无连接、不可靠的传输层协议。在基于 UDP 套接字编程中,数据传输可用函数 sendto 和 recvfrom。以下是基本 UDP 套接字编程过程:sendto 与 recvfrom 函数这两个函数的功能类似于 write 和 read 函数,可用无连接的套接字编程。其定义如下:1. /*函数功能:发送数据;2. *返回值:若成功则返回已发送的字节数,若出错则返回-1;3. *函数原型:4. */5. #include6. 7. ssize_tsendto(intsockfd,void*buff,size_tnbytes,intflags,8. conststructsockaddr*destaddr,socklen_taddrlen);9. 10. /*说明:11. *该函数功能类似于write函数,除了有标识符flags和目的地址信息之外,其他参数一样;12. *13. *flags标识符取值如下:14. *(1)MSG_DONTROUTE勿将数据路由出本地网络15. *(2)MSG_DONTWAIT允许非阻塞操作16. *(3)MSG_EOR如果协议支持,此为记录结束17. *(4)MSG_OOB如果协议支持,发送带外数据18. *19. *若sendto成功,则只是表示已将数据无错误的发送到网络,并不能保证正确到达对端;20. *该函数通过指定目标地址允许在无连接的套接字之间发送数据(例如UDP套接字);21. */22. 23. /*函数功能:接收数据;24. *返回值:以字节计数的消息长度,若无可用消息或对方已经按序结束则返回0,若出错则返回-1;25. *函数原型:26. */27. #include28. 29. ssize_trecvfrom(intsockfd,void*buff,size_tnbytes,intflags,30. structsockaddr*addr,socklen_t*addrlen);31. /*说明:32. *该函数功能与read类似;33. *若addr为非空时,它将包含数据发送者的套接字地址;34. *35. *flags标识符取值如下:36. *(1)MSG_WAITALL等待所有数据可用37. *(2)MSG_DONTWAIT允许非阻塞操作38. *(3)MSG_PEEK查看已读取的数据39. *(4)MSG_OOB如果协议支持,发送带外数据40. */基于 UDP 套接字编程下面我们使用 UDP 协议实现简单的功能,客户端从标准输入读取数据并把它发送给服务器,服务器接收到数据并把该数据回射给客户端,然后客户端收到从服务器回射的数据把它显示到标准输出。其功能实现如下图所示:服务器程序1. /*UDP服务器*/2. #include3. #include4. #include5. #include6. #include7. #include8. 9. #defineSERV_PORT9877/*通用端口号*/10. 11. externvoiderr_sys(constchar*,.);12. externvoiddg_echo(intsockfd,structsockaddr*addr,socklen_taddrlen);13. 14. intmain(intargc,char*argv)15. 16. intsockfd;17. interr;18. structsockaddr_inservaddr,cliaddr;19. 20. /*初始化服务器地址信息*/21. bzero(&servaddr,sizeof(servaddr);22. servaddr.sin_family=AF_INET;23. servaddr.sin_port=htons(SERV_PORT);24. servaddr.sin_addr.s_addr=htonl(INADDR_ANY);25. 26. /*创建套接字,并将服务器地址绑定到该套接字上*/27. if(sockfd=socket(AF_INET,SOCK_DGRAM,0)0)28. err_sys(socketerror);29. err=bind(sockfd,(structsockaddr*)&servaddr,sizeof(servaddr);30. if(err0)31. err_sys(binderror);32. /*服务器处理函数:读取套接字文本行,并把它回射给客户端*/33. dg_echo(sockfd,(structsockaddr*)&cliaddr,sizeof(cliaddr);34. 35. 处理函数1. #includeunp.h2. 3. void4. dg_echo(intsockfd,SA*pcliaddr,socklen_tclilen)5. 6. intn;7. socklen_tlen;8. charmesgMAXLINE;9. 10. for(;)11. len=clilen;12. n=Recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len);13. 14. Sendto(sockfd,mesg,n,0,pcliaddr,len);15. 16. 客户端程序1. /*UDP客户端*/2. #include3. #include4. #include5. #include6. #include7. #include8. #include9. 10. #defineSERV_PORT9877/*通用端口号*/11. 12. externvoiderr_sys(constchar*,.);13. externvoiderr_quit(constchar*,.);14. externvoiddg_cli(FILE*fd,intsockfd,structsockaddr*addr,socklen_taddrlen);15. 16. intmain(intargc,char*argv)17. 18. intsockfd;19. structsockaddr_inservaddr;20. 21. if(argc!=2)22. err_quit(usage:udpcli);23. 24. bzero(&servaddr,sizeof(servaddr);25. servaddr.sin_family=AF_INET;26. servaddr.sin_port=htons(SERV_PORT);27. inet_pton(AF_INET,argv1,&servaddr.sin_addr);28. 29. if(sockfd=socket(AF_INET,SOCK_DGRAM,0)0)30. err_sys(socketerr);31. /*客户端处理函数:从标准输入读入文本行,发送给服务器;接收来自服务器的回射文本,并把它显示到标准输出*/32. dg_cli(stdin,sockfd,(structsockaddr*)&servaddr,sizeof(servaddr);33. 34. exit(0);35. 客户端处理函数1. #includeunp.h2. 3. void4. dg_cli(FILE*fp,intsockfd,constSA*pservaddr,socklen_tservlen)5. 6. intn;7. charsendlineMAXLINE,recvlineMAXLINE+1;8. 9. while(Fgets(sendline,MAXLINE,fp)!=NULL)10. /*把从标准输入读取的文本行发送给服务器套接字*/11. Sendto(sockfd,sendline,strlen(sendline),0,pservaddr,servlen);12. /*接收来自服务器回射的文本行*/13. n=Recvfrom(sockfd,recvline,MAXLINE,0,NULL,NULL);14. 15. recvlinen=0;/*nullterminate*/16. Fputs(recvline,stdout);17. 18. 1. $./serv&2. 1179113. $./client127.0.0.14. sendingtextbasedonUDP5. sendingtextbasedonUDP6. goodbyte.7. goodbyte.数据报丢失由于 UDP 是一种不可靠的传输协议。在上面的客户端 / 服务器 程序中,若数据报在传输的过程中丢失,那么客户端就是阻塞于 dg_cli 处理函数中的 recvfrom 函数调用,等待一个永远都不会达到的服务器应答。也有可能是,客户端数据报成功到达服务器,但是服务器的应答数据报丢失,同样,客户端也将永远阻塞于 recvfrom 函数调用。一般来说,会给客户端 recvfrom 函数调用设置一个超时时钟,但是超时时钟并不能确定是客户端数据报不能到达服务器还是服务器应答不能到达客户端。所以我们可以采用验证接收到的响应。即在 recvfrom 函数调用以返回数据报发送者的 IP 地址和端口号,保留来自数据报所发往服务器的应答。UDP 中使用 connect 函数在没有启动 UDP 服务器的情况下,客户端键入文本行之后,并不会回显该文本行。此时客户端永远阻塞于它的 recvfrom 调用,等待一个永远不会出现的服务器应答。由于服务器没有启动,因此会响应一个端口不可到达的 ICMP 错误消息(即异步错误),但是该 ICMP 错误消息并不会到达客户端进程,因此客户端进程根本不知道发生什么,一直阻塞于它的 recvfrom 调用。为了能使这个异步错误到达客户端进程,我们可以在 UDP 中调用 connect 函数,使其成为一个已连接的 UDP 套接字,但是该链接不会像 TCP 那样引起三次握手过程。内核只是检查是否存在立即可知的错误,并记录对端的 IP 地址和端口号,然后立即返回到调用进程。下面要区分 未连接 UDP 套接字 和 已连接 UDP 套接字: 未连接 UDP 套接字:新创建 UDP 套接字默认为该情况; 已连接 UDP 套接字:对 UDP 套接字调用 connect 函数的结果;已连接 UDP 套接字 相对于 未连接 UDP 套接字 会有以下的变化:1、不能给输出操作指定目的 IP 地址和端口号(因为调用 connect 函数时已经指定),即不能使用 sendto 函数,而是使用 write 或 send 函数。写到已连接 UDP 套接字上的内容都会自动发送到由 connect 指定的协议地址;2、不必使用 recvfrom 函数以获悉数据报的发送者,而改用 read、recv 或 recvmsg 函数。在一个已连接 UDP 套接字上,由内核为输入操作返回的数据报只有那些来自 connect 函数所指定的协议地址的数据报。目的地为这个已连接 UDP 套接字的本地协议地址,发源地不是该套接字早先 connect 到的协议地址的数据报,不会投递到该套接字。即只有发源地的协议地址与 connect 所指定的地址相匹配才可以把数据报传输到该套接字。这样已连接 UDP 套接字只能与一个对端交换数据报;3、由已连接 UDP 套接字引发的异步错误会返回给它们所在的进程,而未连接 UDP 套接字不会接收任何异步错误;UDP 客户端进程或服务器进程只在使用自己的 UDP 套接字与确定的唯一对端通信时,才可以调用 connect 函数。调用 connect 函数的通常是 UDP 客户端。以下是调用 connect 函数的客户端处理函数:1. #includeunp.h2. 3. void4. dg_cli(FILE*fp,intsockfd,constSA*pservaddr,socklen_tservlen)5. 6. intn;7. charsendlineMAXLINE,recvlineMAXLINE+1;8. 9. Connect(sockfd,(SA*)pservaddr,servlen);10. 11. while(Fgets(sendline,MAXLINE,fp)!=NULL)12. 13. Write(sockfd,sendline,strlen(sendline);14
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学术论文选题五大忌讳四个原则辑文编译-4027(同名40088)
- 三农产业供应链优化作业指导书
- 怎么样写好汉语言文学毕业
- 天津音乐学院历届(2009年)硕士研究生学位论文选题一
- 在自主游戏中支持幼儿的深度学习-以大班沙水活动为例
- 利用掺杂技术提高OLED性能及白光OLED色度改善的理论研究
- 企业薪酬管理问题研究综述毕业论文文献综述开题报告任务书
- 汉语言文学设计毕业论文
- 导师对研究生论文评语(三)
- 企业员工心理健康状况调查与分析报告
- 经理面试笔试题目及答案
- 福彩考试题库目录及答案
- 2025年6月大学英语六级考试真题第1套(含答案+听力原文+听力音频)
- 人教统编版高中语文 选择性必修中册《第三单元回到历史现场研习任务》教学设计
- 2025贵州毕节市市直事业单位面向基层公开考调工作人员笔试考试参考试题及答案解析
- 重庆大学硕士研究生论文开题报告格式及范文剖析
- 2025化工维修岗位试题及答案
- 成都交子金融控股集团有限公司招聘笔试题库2025
- 2025浙江省测绘科学技术研究院招聘编外人员12人笔试考试参考试题附答案解析
- 基于PLC的自动洗车控制系统设计
- 2025年铁路招聘考试题库及答案
评论
0/150
提交评论