问题描述
#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;
}
上面的代码被编译为可以在Linux机器上运行.
The above code is compiled to run on a Linux machine.
假设以上代码将数据发送到IP地址128.88.143.113
的计算机.没有UDP套接字绑定到128.88.143.113
上的端口9090
.
Assume that the above code sends data to a machine at IP address 128.88.143.113
. No UDP socket is bound to port 9090
at 128.88.143.113
.
在while
循环中,对send()
的第一个调用成功(数据包实际上从线路上断开;使用trace
对其进行了检查),第二个send()
失败,并通过Connection refused
失败. third send()
成功,第四次失败,依此类推.
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.
我怀疑在首先send()
之后,堆栈会收到保存在套接字结构中的ICMP错误消息(在Linux计算机上的tcpdump
中可见).第二个send()
在看到此错误后失败,并且实际上没有发送任何数据包.第二个send()
还清除套接字结构中的错误.因此,第三个send()
成功,第四个send()
失败,依此类推.
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.
问题:
- 这个假设正确吗?
- 正确的行为应该是什么?是否有任何定义此类行为的RFC标准?
- 由于UDP不保持任何连接状态,所以不是每个
send()
都成功吗?
- Is this assumption correct?
- What should be the correct behavior? Is there any RFC standard defining such behavior?
- Since UDP does not maintain any connection state, shouldn't every
send()
succeed?
推荐答案
根据 udp的Linux手册页:
具体来说, RFC (4.1.3.3)指出:
Specifically the RFC (4.1.3.3) states:
这篇关于connect()之后的UDP发送行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!