开发者社区> 青夜之衫> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

UDP套接口编程

简介:
+关注继续查看

常用的UDP实现的程序:DNS域名系统,NFS网络文件系统,SNMP简单网络管理协议

ssize_t recvfrom(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr * from,socklen_t *addrlen);
ssize_t sendto(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr * to,socklen_t addrlen);
sockfd:描述字
buff:缓冲区指针
nbytes 读写字节数
 UDP服务器端
复制代码
int main(int argc,char ** argv){
int sockfd;
struct sockaddr_in servaddr,cliaddr;
sockfd = Socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(sockfd,(SA *)&servaddr,sizeof(servaddr));
dg_echo(sockfd,(SA *)&cliaddr,sizeof(cliaddr));
}
 
void dg_echo(int sockfd,SA *pcliaddr,socklen_t clilen){
int n;
socklen_t len;
char mesg[MAXLINE];
for(;;){
    len = clilen;
    n = Recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len); //读一个到达的数据包
    Sendto(sockfd,mesg,n,0,pcliaddr,len); //发送回给客户机
}
}
复制代码
SOCK_DGRAM:UDP套接口
1 函数不能终止
2 服务器是迭代服务器,没有fork调用,单一服务器进程处理所有客户。
UDP客户机程序:
复制代码
int main(int argc,char ** argv){
int sockfd;
struct sockaddr_t servaddr;
if(argc != 2)
    err_quit("usage:udpcli<IPaddress>");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET,argv[1],&servaddr,sin_addr); //装填套接字
sockfd = Socket(AF_INET,SOCK_DGRAM,0);
dg_cli(stdin,sockfd,(SA *)&servaddr,sizeof(servaddr));
exit(0);
}
void dg_cli(FILE *fp,int sockfd,const SA *pservaddr,socklen_t servlen){
int n;
char sendline[MAXLINE],recvline[MAXLINE+1];
while(Fgets(sendline,MAXLINE,fp) != NULL){ //从标准输入读一行
    Sendto(sockfd,sendline,strlen(sendline),0,pservaddr,servlen); //使用sendto发送给服务器
    n = Recvfrom(sockfd,recvline,MAXLINE,0,NULL,NULL); //使用recvfrom接收服务器回射,NULL无视目标主机
    recvline[n] = 0; 
    Fputs(recvline,stdout); //fputs输出回射行到标准输出
}
}
复制代码
改进的dg_cli
复制代码
void dg_cli(FILE *fp,int sockfd,const SA * pservaddr,socklen_t servlen){
int n;
char sendline[MAXLINE],recvline[MAXLINE+1];
socklen_t len;
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,&len);
    if(len != servlen || memcpy(pservaddr,preply_addr,len) != 0){
        printf("reply from %s (ignored)\n");
                    Sock_ntop(preply_addr,len);
        continue;
    }
    recvline[n] = 0;
    Fputs(recvline,stdout);
}
}
复制代码
解决办法:
1 给定由recvfrom返回的IP,在DNS中查找服务器验证
2 服务器配置每个IP地址创建套接口,捆绑IP地址此套接口,
仅在进程已将UDP套接口连接到确切的对方后,这些一步错误才返回给进程。
已连接的UDP套接口上调用connect达到下面两个目的:
1 指定IP地址和端口号
2 断开套接口
使用connect连接后再调用read write
复制代码
void dg_cli(FILE *fp,int sockfd,const SA * pservaddr,socklen_t servlen){
    int n;
    char sendline[MAXLINE],recvline[MAXLINE+1];
    Connect(sockfd,(SA *)pservaddr,servlen);
    while(Fgets(sendline,MAXLINE,fp)!= NULL){
        Write(sockfd,sendline,strlen(sendline));
        n=Read(sockfd,recvline,MAXLINE);
        recvline[n] = 0;
        Fputs(recvline,stdout);
    }
}
复制代码
对发送的UDP进行统计:
复制代码
static void recvfrom_int(int);
static int count;
void dg_echo(int sockfd,SA *pcliaddr,socklen_t clilen){
    socklen_t len;
    char mesg[MAXLINE];
    Signal(SIGINT,recvfrom_int);
    for(;;){
        len = clilen;
        Recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len);
 
        count++;
    }
}
static void recvfrom_int(int signo){
    printf("\nreceived %d datagrams\n",count);
    exit(0);
}
复制代码
UDP与TCP的服务器复用:
复制代码
int main(int argc,char ** argv){
int listenfd,connfd,updfd,nready,maxfdp1;
char mesg[MAXLINE];
pid_t childpid;
fd_set rset;
ssize_t n;
socklen_t len;
const int on = 1;
struct sockaddr_in cliaddr,servaddr;
void sig_child(int);
 
listenfd = Socket(AF_INET,SOCKSTREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_add=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERV_PORT);
Setsockopt(listenfd,SOL_SOCKET,SO_RESSEADDR,&on,sizeof(on));
Bind(listenfd,(SA *)&servaddr,sizeof(servaddr));
Listen(listenfd,LISTENQ);
 
updfd=Socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERV_PORT);
Bind(udpfd,(SA *)&servaddr,sizeof(servaddr));
 
Signal(SIGCHLD,sig_chld);
FD_ZERO(&rset);
maxfdp1=max(listenfd,udpfd)+1;
for(;;){
    FD_SET(listenfd,&rset);
    FD_SET(udpfd,&rset);
    if((nready=select(maxfdp1,&rset,NULL,NULL,NULL,NULL))<0){
        if(errno==EINTR)
            continue;
        else
            err_sys("select error");
    }
    if(FD_ISSET(listenfd,&rset)){
        len = sizeof(cliaddr);
        connfd=Accept(listenfd,(SA *)&cliaddr,&len);
        if((childpid=Fork())==0){
            Close(listenfd);
            str_echo(connfd);
            exit(0);
        }
        Close(connfd);
    }
    if(FD_ISSET(udpfd,&rset)){
        len=sizeof(cliaddr);
        n=Recvfrom(udpfd,mesg,MAXLINE,0,(SA *)&cliaddr,&len);
        Sendto(udpfd,mesg,n,0,(SA *)&cliaddr,len);
    }
}
}
复制代码

 

本文转自博客园xingoo的博客,原文链接:UDP套接口编程,如需转载请自行联系原博主。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
套接字编程:UDP通信程序编写、套接字接口、字节序转换接口
套接字编程:UDP通信程序编写、套接字接口、字节序转换接口
0 0
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.14 UDP中的外出接口的确定
已连接UDP套接字还可用来确定用于某个特定目的地的外出接口。这是由connect函数应用到UDP套接字时的一个副作用造成的:内核选择本地IP地址(假设其进程未曾调用bind显式指派它)。这个本地IP地址通过为目的IP地址搜索路由表得到外出接口,然后选用该接口的主IP地址而选定。
1700 0
猿创征文|网络原理——UDP/TCP协议
本文主要介绍在TCP/IP的五层协议模型中,传输层的最常见的两个协议——UDP协议与TCP协议。TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输。下边我们来一起具体了解这两个协议。
0 0
猿创征文|UDP/TCP网络编程
猿创征文|UDP/TCP网络编程
0 0
计算机网络学习26:TCP/UDP对比区别、TCP流量控制、拥塞控制、超时重传时间的选择、可靠传输的实现
UDP: User Datagram Protocol 用户数据报协议 TCP: Transmission Control Protocol 传输控制协议 同时这里指的连接是指逻辑连接,而不是物理连接。
0 0
网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(2)
网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(2)
0 0
网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(1)
网络协议报文理解刨析篇二(再谈Http和Https), 加上TCP/UDP/IP协议分析(理解着学习), 面试官都惊讶你对网络的见解(1)
0 0
Java网络编程:UDP/TCP实现实时聊天、上传图片、下载资源等
ip地址的分类: 1、ipv4、ipv6 127.0.0.1:4个字节组成,0-255,42亿;30亿都在北美,亚洲就只有4亿 2011年就用尽了。
0 0
Java基础进阶网络编程-TCP和UDP协议
Java基础进阶网络编程-TCP和UDP协议
0 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载