当前位置: 首页 > news >正文

台州建设公司网站怡梦姗网站做么

台州建设公司网站,怡梦姗网站做么,网址生成app一键生成器,自媒体代运营《TCP IP网络编程》第六章#xff1a;基于 UDP 的服务端/客户端 UDP 套接字的特点#xff1a; 通过寄信来说明 UDP 的工作原理#xff0c;这是讲解 UDP 时使用的传统示例#xff0c;它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址#xff0c;之后…《TCP IP网络编程》第六章基于 UDP 的服务端/客户端 UDP 套接字的特点 通过寄信来说明 UDP 的工作原理这是讲解 UDP 时使用的传统示例它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址之后贴上邮票放进邮筒即可。当然信件的特点使我们无法确认信件是否被收到。邮寄过程中也可能发生信件丢失的情况。也就是说信件是一种不可靠的传输方式UDP 也是一种不可靠的数据传输方式。 不过这种比喻只是形容协议工作方式并不包含数据交换速率。实际正好相反TCP的速度无法超过UDP但在收发某些类型的数据时可能接近UDP。 因为 UDP 没有 TCP 那么复杂所以编程难度比较小性能也比 TCP 高。在更重视性能的情况下可以选择 UDP 的传输方式。 TCP 与 UDP 的区别很大一部分来源于流控制。也就是说 TCP 的生命在于流控制。 UDP 的工作原理 从图中可以看出IP 的作用就是让离开主机 B 的 UDP 数据包准确传递到主机 A 。但是把 UDP 数据包最终交给主机 A 的某一 UDP 套接字的过程是由 UDP 完成的。UDP 的最重要的作用就是根据端口号将传到主机的数据包交付给最终的 UDP 套接字。  UDP 的高效使用 UDP 也具有一定的可靠性。对于通过网络实时传递的视频或者音频时情况有所不同。对于多媒体数据而言丢失一部分数据也没有太大问题这只是会暂时引起画面抖动或者出现细微的杂音。但是要提供实时服务速度就成为了一个很重要的因素。因此流控制就显得有一点多余这时就要考虑使用 UDP 。TCP 比 UDP 慢的原因主要有以下两点 收发数据前后进行的连接设置及清除过程。收发过程中为保证可靠性而添加的流控制。 如果收发的数据量小但是需要频繁连接时UDP 比 TCP 更高效。 实现基于 UDP 的服务端/客户端 UDP 中的服务端和客户端不像 TCP 那样在连接状态下交换数据因此与 TCP 不同无需经过连接过程。也就是说不必调用 TCP 连接过程中调用的 listen 和 accept 函数。UDP 中只有创建套接字和数据交换的过程。 TCP 中套接字之间应该是一对一的关系。若要向 10 个客户端提供服务除了守门的服务器套接字之外还需要 10 个服务器套接字。但在 UDP 中不管是服务器端还是客户端都只需要 1 个套接字。只需要一个 UDP 套接字就可以向任意主机传输数据如图所示 图中展示了 1 个 UDP 套接字与 2 个不同主机交换数据的过程。也就是说只需 1 个 UDP 套接字就能和多台主机进行通信。 创建好 TCP 套接字以后传输数据时无需加上地址信息。因为 TCP 套接字将保持与对方套接字的连接。换言之TCP 套接字知道目标地址信息。但 UDP 套接字不会保持连接状态UDP 套接字只有简单的邮筒功能因此每次传输数据时都需要添加目标的地址信息。这相当于寄信前在信件中填写地址。接下来是 UDP 的相关函数  #include sys/socket.h ssize_t sendto(int sock, void *buff, size_t nbytes, int flags,struct sockaddr *to, socklen_t addrlen); /* 成功时返回发送的字节数失败时返回 -1 sock: 用于传输数据的 UDP 套接字 buff: 保存待传输数据的缓冲地址值 nbytes: 待传输的数据长度以字节为单位 flags: 可选项参数若没有则传递 0 to: 存有目标地址的 sockaddr 结构体变量的地址值 addrlen: 传递给参数 to 的地址值结构体变量长度 */ 上述函数与之前的 TCP 输出函数最大的区别在于此函数需要向它传递目标地址信息。接下来介绍接收 UDP 数据的函数。UDP 数据的发送并不固定因此该函数定义为可接受发送端信息的形式也就是将同时返回 UDP 数据包中的发送端信息。 #include sys/socket.h ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags,struct sockaddr *from, socklen_t *addrlen); /* 成功时返回接收的字节数失败时返回 -1 sock: 用于传输数据的 UDP 套接字 buff: 保存待传输数据的缓冲地址值 nbytes: 待传输的数据长度以字节为单位 flags: 可选项参数若没有则传递 0 from: 存有发送端地址信息的 sockaddr 结构体变量的地址值 addrlen: 保存参数 from 的结构体变量长度的变量地址值。 */ 编写 UDP 程序的最核心的部分就在于上述两个函数。 实验 UDP 的回声服务器端/客户端 服务端 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/socket.h#define BUF_SIZE 30 void error_handling(char *message);int main(int argc, char *argv[]) {int serv_sock;char message[BUF_SIZE];int str_len;socklen_t clnt_adr_sz;struct sockaddr_in serv_adr, clnt_adr;if (argc ! 2){printf(Usage : %s port\n, argv[0]);exit(1);}//创建 UDP 套接字后向 socket 的第二个参数传递 SOCK_DGRAMserv_sock socket(PF_INET, SOCK_DGRAM, 0);if (serv_sock -1)error_handling(UDP socket creation eerror);memset(serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family AF_INET;serv_adr.sin_addr.s_addr htonl(INADDR_ANY);serv_adr.sin_port htons(atoi(argv[1]));//分配地址接受数据不限制数据传输对象if (bind(serv_sock, (struct sockaddr *)serv_adr, sizeof(serv_adr)) -1)error_handling(bind() error);while (1){clnt_adr_sz sizeof(clnt_adr);str_len recvfrom(serv_sock, message, BUF_SIZE, 0,(struct sockaddr *)clnt_adr, clnt_adr_sz);//通过上面的函数调用同时获取数据传输端的地址。正是利用该地址进行逆向重传sendto(serv_sock, message, str_len, 0,(struct sockaddr *)clnt_adr, clnt_adr_sz);}close(serv_sock);return 0; }void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1); } 客户端 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/socket.h#define BUF_SIZE 30 void error_handling(char *message);int main(int argc, char *argv[]) {int sock;char message[BUF_SIZE];int str_len;socklen_t adr_sz;struct sockaddr_in serv_adr, from_adr;if (argc ! 3){printf(Usage : %s IP port\n, argv[0]);exit(1);}//创建 UDP 套接字sock socket(PF_INET, SOCK_DGRAM, 0);if (sock -1)error_handling(socket() error);memset(serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family AF_INET;serv_adr.sin_addr.s_addr inet_addr(argv[1]);serv_adr.sin_port htons(atoi(argv[2]));while (1){fputs(Insert message(q to quit): , stdout);fgets(message, sizeof(message), stdin);if (!strcmp(message, q\n) || !strcmp(message, Q\n))break;//向服务器传输数据,会自动给自己分配IP地址和端口号sendto(sock, message, strlen(message), 0,(struct sockaddr *)serv_adr, sizeof(serv_adr));adr_sz sizeof(from_adr);str_len recvfrom(sock, message, BUF_SIZE, 0,(struct sockaddr *)from_adr, adr_sz);message[str_len] 0;printf(Message from server: %s, message);}close(sock);return 0; }void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1); } 实验结果 UDP 客户端套接字的地址分配  UDP 客户端缺少了把IP和端口分配给套接字的过程。TCP 客户端调用 connect 函数自动完成此过程而 UDP 中连能承担相同功能的函数调用语句都没有。究竟在什么时候分配IP和端口号呢 UDP 程序中调用 sendto 函数传输数据前应该完成对套接字的地址分配工作因此调用 bind 函数。当然bind 函数在 TCP 程序中出现过但 bind 函数不区分 TCP 和 UDP也就是说在 UDP 程序中同样可以调用。另外如果调用 sendto 函数尚未分配地址信息则在首次调用 sendto 函数时给相应套接字自动分配 IP 和端口。而且此时分配的地址一直保留到程序结束为止因此也可以用来和其他 UDP 套接字进行数据交换。当然IP 用主机IP端口号用未选用的任意端口号。 综上所述调用 sendto 函数时自动分配IP和端口号因此UDP 客户端中通常无需额外的地址分配过程。所以之前的示例中省略了该过程。这也是普遍的实现方式。 UDP 的数据传输特性和调用 connect 函数 前面说得 TCP 数据传输中不存在数据边界这表示「数据传输过程中调用 I/O 函数的次数不具有任何意义」 相反UDP 是具有数据边界的下一传输中调用 I/O 函数的次数非常重要。因此输入函数的调用次数和输出函数的调用次数应该完全一致这样才能保证接收全部已经发送的数据。例如调用 3 次输出函数发送的数据必须通过调用 3 次输入函数才能接收完。通过一个例子来进行验证 服务端代码 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/socket.h#define BUF_SIZE 30 void error_handling(char *message);int main(int argc, char *argv[]) {int sock;char message[BUF_SIZE];struct sockaddr_in my_adr, your_adr;socklen_t adr_sz;int str_len, i;if (argc ! 2){printf(Usage : %s port\n, argv[0]);exit(1);}sock socket(PF_INET, SOCK_DGRAM, 0);if (sock -1)error_handling(socket() error);memset(my_adr, 0, sizeof(my_adr));my_adr.sin_family AF_INET;my_adr.sin_addr.s_addr htonl(INADDR_ANY);my_adr.sin_port htons(atoi(argv[1]));if (bind(sock, (struct sockaddr *)my_adr, sizeof(my_adr)) -1)error_handling(bind() error);for (i 0; i 3; i){sleep(5);adr_sz sizeof(your_adr);str_len recvfrom(sock, message, BUF_SIZE, 0,(struct sockaddr *)your_adr, adr_sz);printf(Message %d: %s \n, i 1, message);}close(sock);return 0; }void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1); } 客户端代码  #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/socket.h#define BUF_SIZE 30 void error_handling(char *message);int main(int argc, char *argv[]) {int sock;char msg1[] Hi!;char msg2[] Im another UDP host!;char msg3[] Nice to meet you;struct sockaddr_in your_adr;socklen_t your_adr_sz;if (argc ! 3){printf(Usage : %s IP port\n, argv[0]);exit(1);}sock socket(PF_INET, SOCK_DGRAM, 0);if (sock -1)error_handling(socket() error);memset(your_adr, 0, sizeof(your_adr));your_adr.sin_family AF_INET;your_adr.sin_addr.s_addr inet_addr(argv[1]);your_adr.sin_port htons(atoi(argv[2]));sendto(sock, msg1, sizeof(msg1), 0,(struct sockaddr *)your_adr, sizeof(your_adr));sendto(sock, msg2, sizeof(msg2), 0,(struct sockaddr *)your_adr, sizeof(your_adr));sendto(sock, msg3, sizeof(msg3), 0,(struct sockaddr *)your_adr, sizeof(your_adr));close(sock);return 0; }void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1); } 客户端调用3次sendto函数以传输数据服务端则调用了3次recvfrom函数以接受数据。recvfrom函数调用间隔为5秒因此调用recvfrom函数前已调用了3次sendto函数。也就是说此时数据已经传输到bound_host1.c。如果是TCP程序这时只需调用1次输入函数即可读入数据。UDP则不同在这种情况下也需要调用3次recvfrom函数。可通过以下运行结果进行验证。 从服务端结果可以看出共调用了3次recvfrom函数这就证明了必须在UDP通信过程中使I/O函数调用次数保持一致。 已连接connectUDP 套接字与未连接unconnectedUDP 套接字      TCP 套接字中需注册待传传输数据的目标IP和端口号而在 UDP 中无需注册。因此通过 sendto 函数传输数据的过程大概可以分为以下 3 个阶段 第 1 阶段向 UDP 套接字注册目标 IP 和端口号第 2 阶段传输数据第 3 阶段删除 UDP 套接字中注册的目标地址信息。 每次调用 sendto 函数时重复上述过程。每次都变更目标地址因此可以重复利用同一 UDP 套接字向不同目标传递数据。这种未注册目标地址信息的套接字称为未连接套接字反之注册了目标地址的套接字称为连接 connected 套接字。显然UDP 套接字默认属于未连接套接字。当一台主机向另一台主机传输很多信息时上述的三个阶段中第一个阶段和第三个阶段占整个通信过程中近三分之一的时间缩短这部分的时间将会大大提高整体性能。 创建已连接 UDP 套接字过程格外简单只需针对 UDP 套接字调用 connect 函数 sock socket(PF_INET, SOCK_DGRAM, 0); memset(adr, 0, sizeof(adr)); adr.sin_family AF_INET; adr.sin_addr.s_addr inet_addr(argv[1]); adr.sin_port htons(atoi(argv[2])); connect(sock, (struct sockaddr *)adr, sizeof(adr)); 上述代码看似与 TCP 套接字创建过程一致但 socket 函数的第二个参数分明是 SOCK_DGRAM 。也就是说创建的的确是 UDP 套接字。当然针对 UDP 调用 connect 函数并不是意味着要与对方 UDP 套接字连接这只是向 UDP 套接字注册目标IP和端口信息。 之后就与 TCP 套接字一致每次调用 sendto 函数时只需传递信息数据。因为已经指定了收发对象所以不仅可以使用 sendto、recvfrom 函数还可以使用 write、read 函数进行通信。 习题 1、UDP 为什么比 TCP 快为什么 TCP 传输可靠而 UDP 传输不可靠 UDP比TCP快的原因是UDP没有建立连接和拥塞控制的开销并且没有重传机制。TCP传输可靠的原因是TCP通过建立连接、序号管理和重传机制来确保数据的可靠传输和完整性。 2、UDP 数据报向对方主机的 UDP 套接字传递过程中IP 和 UDP 分别负责哪些部分 IP的作用就是让离开主机的 UDP 数据包准确传递到另一个主机。但把 UDP 包最终交给主机的某一 UDP 套接字的过程则是由 UDP 完成的。UDP 的最重要的作用就是根据端口号将传到主机的数据包交付给最终的 UDP 套接字。 3、UDP 一般比 TCP 快但根据交换数据的特点其差异可大可小。请你说明何种情况下 UDP 的性能优于 TCP 如果收发数据量小但需要频繁连接时UDP 比 TCP 更高效。 4、客户端 TCP 套接字调用 connect 函数时自动分配IP和端口号。UDP 中不调用 bind 函数那何时分配IP和端口号 在首次调用 sendto 函数时自动给相应的套接字分配IP和端口号。而且此时分配的地址一直保留到程序结束为止。这种临时分配的机制使得UDP套接字可以在不调用bind函数的情况下进行通信。UDP套接字的地址和端口号分配由操作系统自动完成无需用户显式指定。这也是UDP相比TCP更加灵活和简单的一点。 5、TCP 客户端必须调用 connect 函数而 UDP 可以选择性调用。请问在 UDP 中调用 connect 函数有哪些好处 UDP通过 sendto 函数传输数据的过程大概可以分为以下 3 个阶段 第 1 阶段向 UDP 套接字注册目标 IP 和端口号第 2 阶段传输数据第 3 阶段删除 UDP 套接字中注册的目标地址信息。 当一台主机向另一台主机传输很多信息时上述的三个阶段中第一个阶段和第三个阶段占整个通信过程中近三分之一的时间使用connect函数可以节省这些时间。
http://www.hkea.cn/news/14497659/

相关文章:

  • 宁德做网站公司做动画视频的网站有哪些
  • 华为公司网站建设方案模板下载wordpress中文免费主题下载地址
  • 网站快照没了免费素材网站视频
  • 网站稳定期的推广网站建设系统开发感想与收获
  • 韩国设计app网站有哪些网站服务器有哪些
  • 网站修改标题有哪些网站可以做海报
  • 如何做网站编辑女生适合做seo吗
  • 郑州网站推广服务在合肥做网站前端月薪大概多少
  • 茂南手机网站建设公司临湘建设局网站
  • 网站seo外链建设擦边球网站做国内还是国外好
  • 我要浏览国外网站怎么做星空传媒有限公司网站
  • 想建个企业网站佛山网站建设解决方案
  • 成交型网站建设公司小程序快速搭建
  • 文昌网站建设 myvodo做购物网站怎么赚钱
  • 拓展公司网站建设房产发布平台有哪些
  • 苏州 建设中心网站国产软件开发平台
  • 自己做的网站网页错位ui界面设计作品模板
  • 泰州建设信息网站大连网站推广价格
  • 医院网站建设趋势做团购网站有什么难处
  • 防蜘蛛抓取网站代码广州网站建设网站开发
  • 临沂做企业网站网页制作实训报告总结
  • 可以建设网站沈阳互联网公司排名
  • 怀化职院网站深圳市住房和建设局网官网
  • 优质的房产网站建设wordpress 首页变量
  • 外贸网站建设入门开发区人才市场官网
  • 专门 做鞋子团购的网站有哪些医院网站建设报价
  • 有没得办法可以查询一个网站有没得做竞价呀秒火食品代理网
  • 福州公司网站建设_网站备案和服务器备案
  • 公司网站建设一般要多少钱报班学平面设计
  • 甘肃建设厅网站定制app开发平台