udp connect

49次阅读

共计 1642 个字符,预计需要花费 5 分钟才能阅读完成。

在 udp 上使用 connect 的情况:
需要获取 icmp 的错误信息.
2. 如果需要向同一个 ip 地址多次 sendto , 用以减少不断的连接, 断开. 提高性能
注意:
udp 的 connect 只记录 (注册) 对端的套接字结构(ip,port) , 并不会像 tcp 进行 3 次握手. 所以无法第一时间获取连接错误;
这种称为有连接的 udp 套接字 也只能 发送 / 接受 connect 中的指定的 ip,port;
下面一个例子说明了 sendto 只是向内核缓冲区复制数据 就返回了. 并不会产生 icmp 错误信息
无 connect 版本
int main(int argc, char**argv)
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0); //udp
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_port = htons(PORT); // 没有服务器
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(“127.0.0.1”);
char send[100],recv[100];
int n = 0;

while(1){
n = read(0,send,100);
n =sendto(sockfd,send,n,0,(SA*)&sin,sizeof(sin)); // 发送到缓冲区就返回, 没有 icmp 错误信息
printf(“sendto return : %d\n” , n);
n = recvfrom(sockfd,recv,100,0,0,0); // 此时将一直阻塞在这里 等待接受数据
printf(“recvfrom return :%d\n”,n);
recv[n] =0;
printf(“buf : %s\n”, recv);
}

return 0;
}

通过调用 connect 后的代码, 把 sendto , recvfrom 换成了 read , write (不是一定要换, 只是后 2 个函数参数少)
通过 connect 后的 udp 套接字 可以收到 icmp 错误信息了, 在 read 返回后将产生错误, write 仅仅是复制数据到缓冲区;
#include “util.h”
#include <netdb.h>
extern int h_errno;

int main(int argc, char**argv)
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_port = htons(PORT);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(“127.0.0.1”);
char send[100],recv[100];
int n = 0;
puts(“begin connect”);
int r = connect(sockfd,(SA*)&sin,sizeof(sin)); //udp 的连接在这一步不会有问题 与 tcp 不同, tcp 会 3 次握手, udp 没有
if(r < 0){
perror(“connect error”);
return 0;
}
printf(“connect return :%d , errno:%d\n”, r, errno);

while(1){
n = read(0,send,100);
n = write(sockfd,send,n); // 这里也不会有问题, 仅仅发送到缓冲区.
printf(“sendto return : %d\n” , n);

n = read(sockfd,recv,100); // 这里将返回错误 Connection refused, 这是没 connect 前所没有的
if(n < 0){
printf(“***recvfrom return :%d ,error:%d\n”,n,errno);
perror(“***read error”);
} else {
recv[n] =0;
printf(“buf : %s\n”, recv);
}
}

return 0;
}

正文完
 0