UDP用 connect后 send err出错实例---stackoverflow

http://stackoverflow.com/questions/4397195/udp-send-behaviour-after-connect

My总结:

在发送udp包时,如果调用connect,因是无连接协议,返回的错误信息,可能是上一次发送一个udp失败的错误信息。


================

#include <stdio.h>  
#include <errno.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  

int main()  
{    
    struct sockaddr_in addr;  
    int fd, cnt,ret;  
    char ch = 'y',msg[] ="How are you";  

    if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {  
        printf("Error: socket");  
        exit(1);  
    }
    printf("\nDone socket\n");  

    /* set up destination address */  
    memset(&addr,0,sizeof(addr));  
    addr.sin_family=AF_INET;  
    addr.sin_addr.s_addr=inet_addr("128.88.143.113");  
    addr.sin_port=htons(9090);  

    ret=connect(fd,(struct sockaddr *)&addr,sizeof(addr));  
    perror("Connect:");  

    while(ch == 'y'){  
        cnt =  send(fd,msg,sizeof(msg),0);  
        if(cnt < 0)  
        perror("send:");  
        printf("\nNumber of bytes sent = %d , \n",cnt);  
        printf("Continue (y/n)\n");  
        scanf(" %c",&ch);  

     }

     return 0;  
}  

The above code is run on a Linux machine.

Assume that the above code sends data to a machine 128.88.143.113. No UDP socket is bound to port 9090 on 128.88.143.113.

In the while loop, the first call to send succeeds(the packet actually goes out on the wire; checked it using trace) and the second send() fails with 'Connection refused'. The third send() succeeds and the forth fails and so on...

I suspect that after first send the stack receives an ICMP error message(seen in tcpdump on the Linux machine) which is saved in the socket structure. The second send() fails upon seeing this error and no packet is actually sent out. The second send() also clears the error in the socket structure. Therefore the third send() succeeds and the forth fails and so on.

Questions: 1.Is this hypothesis correct? 2. What should be the correct behavior? Is there any standard RFC defining the behavior? 3. Since UDP does not maintain any connection state, shouldn't every send() succeed?



/

According to the linux man page for udp:

All fatal errors will be passed to the user as an error return even when the socket is not connected. This includes asynchronous errors received from the network. You may get an error for an earlier packet that was sent on the same socket. This behaviour differs from many other BSD socket implementations which don't pass any errors unless the socket is connected. Linux's behaviour is mandated by RFC 1122.

Specifically the RFC (4.1.3.3) states:

UDP MUST pass to the application layer all ICMP error messages that it receives from the IP layer. Conceptually at least, this may be accomplished with an upcall to the ERROR_REPORT routine

///

Your hypothesis is correct. The Linux udp(7) man page describes the situation thus:

All fatal errors will be passed to the user as an error return even when the socket is not connected. This includes asynchronous errors received from the network. You may get an error for an earlier packet that was sent on the same socket.
This behavior differs from many other BSD socket implementations which don't pass any errors unless the socket is connected. Linux's behavior is mandated by RFC 1122.

When the IP_RECVERR option is enabled all errors are stored in the socket error queue and can be received by recvmsg(2) with theMSG_ERRQUEUE flag set.

问题:

1.在send success的情况下,为什么会出现ICMP的err msg?

2、那平常udp,在connect情况下,都是这么传输的啊 ?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值