在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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。