资源预览内容
第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
第9页 / 共11页
第10页 / 共11页
亲,该文档总共11页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
基本基本 UDPUDP 套接口编程套接口编程基本 UDP 套接口编程.txt24 生活如海,宽容作舟,泛舟于海,方知海之宽阔;生活如山,宽容为径,循径登山,方知山之高大;生活如歌,宽容是曲,和曲而歌,方知歌之动听。基本 UDP 套接口编程-第八军团 时间:2004-1-17 21:32:27 概述UDP无连接的 connectionless 不可靠的 unreliable 数据报协议 datagram应用:DNS, NFS, SNMP, ICQTCP面向连接的 connection-oriented 可靠的 reliable 字节流协议 byte stream应用:www, telnet ,ftp-UDP 客户-服务器程序的套接口函数recvfrom 和 sendto 函数#include ssize_t recvfrom(int sockfd, void *buff, size nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);sockfd: 描述字buff: 指向输入缓冲器的指针nbytes: 读字节大小flag: 标志:0from :对方协议地址addrlen: 对方协议地址长度函数返回值: 读入数据的长度,可以为 0.ssize_t sendto(int sockfd, void *buff, size nbytes, int flags, const struct sockaddr *to, socklen_t *addrlen);TCP 的字节流输入输出函数:ssize_t readn(int sockfd, void *buff, size nbytes) ; ssize_t writen (int sockfd, void *buff, size nbytes);-UDP 回射服务器程序/服务器 main 主程序#include “unp.h“Int main(int argc, char *argv)int sockfd; /定义套接字struct sockaddr_in servaddr, cliaddr; /IPv4 套接口地址定义sockfd = Socket(AF_INET, SOCK_DGRAM, 0); /建立 UDP 套接字bzero( /地址结构清零servaddr.sin_family = AF_INET; /IPv4 协议servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/内核指定地址servaddr.sin_port = htons(SERV_PORT); /9877 端口/*分配协议地址,绑定端口*/Bind(sockfd, (SA *) /* 回射子程序*/dg_echo(sockfd, (SA *) 回射子程序:include “unp.h“void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)int n; /读入字节数socklen_t len; /协议地址长度, 没有这个参数用 clilen 也可以char mesgMAXLINE;for ( ; ; ) len = clilen;/* 读入一行 */n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, /* 回射到对方套接口 */Sendto(sockfd, mesg, n, 0, pcliaddr, len);-UDP 回射客户程序/客户 main 主程序include “unp.h“int main(int argc, char *argv) /命令行的第二个参数代表服务器地址 int sockfd; /套接字struct sockaddr_in servaddr; /服务器地址结构/* 必须在命令行指定服务器地址*/if (argc != 2) err_quit(“usage: udpcli “);bzero( /地址结构清零servaddr.sin_family = AF_INET; /IPv4servaddr.sin_port = htons(SERV_PORT); /9877 端口/*网络字节序的 IP 地址*/Inet_pton(AF_INET, argv1, /*建立 UPD 套接口*/sockfd = Socket(AF_INET, SOCK_DGRAM, 0);/*回射客户端子程序, stdin 为标准输入:键盘*/dg_cli(stdin, sockfd, (SA *) exit(0); /子程序结束后退出程序/客户端回射子程序#include “unp.h“void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)int n; /读入字节数char sendlineMAXLINE, recvlineMAXLINE + 1; / 1:结束标志占用/* 从键盘读入一行 */while (Fgets(sendline, MAXLINE, fp) != NULL) /如果不是D结束/* 将读入行发送到服务器套接口*/Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);/*从读入回射,读入字节数为 n, 不关心从何处读入n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);recvlinen = 0; /* recvline 字符串的结束标志*/Fputs(recvline, stdout); /输出到标准输出:显示器 /while 循环结束:直到从键盘读入结束符D 为止-验证收到的响应void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)int n; socklen_t len;char sendlineMAXLINE, recvlineMAXLINE + 1;struct sockaddr *preply_addr; /对方 (回应)地址指针preply_addr = Malloc(servlen); /分配地址结构while (Fgets(sendline, MAXLINE, fp) != NULL) Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);len = servlen; /* 读入一行,并获得对方的套接口地址*/n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, /*对方套接口地址长度和指定服务器地址长度不相同*/*或套接口地址结构也不相同时,*/if (len != servlen | memcmp(pservaddr, preply_addr, len) != 0) printf(“reply from %s (ignored)n”, /忽略回射行,并输出对方地址Sock_ntop(preply_addr, len) ); continue; /下一轮循环recvlinen = 0; /* null terminate */Fputs(recvline, stdout);-服务器进程未运行回射服务器-客户端程序执行的基本步骤:启动服务器启动客户程序服务器没有启动,客户端没有回射行,一直等待用 tcpdump 观察数据包 tcpdump icmp or arp or port 9877有 ARP 请求和应答:端口不可达 port . unreachable异步错误:由 sendto 引起的 ICMP 错误, 而 sendto 本身并不返回该错误用已连接套接口才能返回到 UDP 套接口,需要调用 connect.-UDP 调用 CONNECT在末连接 UDP 套接口上给两个数据报调用函数 sendto 导致内核执行下列六步:1.连接套接口;2.输出第一个数据报3.断开套接口连接;4.连接套接口,5.输出第二个数据报;6.断开套接口连接已连接套接口发送两个数据报的导致内核执行如下步骤;1.连接套接口;2.输出第一个数据报;3.输出第二个数据报。对同一套接口发送时,耗时减少 1/3-dg_cli 函数(修订版)调用 connect 函数(有 ICMP 错误返回)用 read 和 write 代替 sendto 和 recvform/* 调用 connect 函数的 UDP 回射客户子程序*/void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)int n;char sendlineMAXLINE, recvlineMAXLINE + 1;/* 与对方建立连接 */Connect(sockfd, (SA *) pservaddr, servlen);while (Fgets(sendline, MAXLINE, fp) != NULL) Write(sockfd, sendline, strlen(sendline);n = Read(sockfd, recvline, MAXLINE);recvlinen = 0; /* null terminate */Fputs(recvline, stdout);-UPD 缺乏流量控制UDP 没有流量控制,它是不可靠的。如果 UDP 发送方比 UDP 接收方运行速度快, 可能导致接收缓冲区满而造成数据报丢失。对服务器或客户来说,并没有给出任何指示说这些数据报已丢失。UDP 套接口缓冲区由 UDP 给特定套接口排队的 UDP 数据报数目受限于套接口接收缓冲区的大小。用 SO_RCVBUF 套接口选项改变此值,可以改善数据报丢失
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号