Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1792229
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: LINUX

2010-03-18 18:18:39

一、UDP的connect函数,并不进行3次握手机制,而仅仅是指定了目的ip和port而已。对于已经connect过的套接口
(1)不能再使用sendto或recvfrom函数,因为connect已经指定ip和port,所以只能用write和read函数。
(2)UDP中,connect可以多次使用,也可以断开connect后重新指定ip和port。。设置地址族为AF_UNSPEC,再调用 connect,则可以断开此接口。
实际上,sendto的操作即是循环 连接套接口,输出数据,关闭套接口 这3个动作的。
(3)一个socket只能connect一个目的主机。仅在进程用udp套接口与确定的唯一对方进行通信时,才调用connect。

二、
UDP中 ,长度为0的数据包是可以发送的,会生成一个包含IP头部(ipv4-20字节,ipv6-40字节),和8字节UDP头部,以及没有数据的 IP数据包,recvfrom返回0。
所以,当recvfrom返回0,并不意味着对方关闭了连接。实际上,UDP本来就没有连接可言。


TCP服务器一般是并发多进程的,UDP服务器一般是迭代的 。。

如果服务端进程未开启,那么客户端往其发送udp数据包时,会返回ICMP不可到达错误,但是这个错误一般不返回到客户端进程,因为ICMP不可到达错误 是异步错误,如果客户端发送多个UDP,其中一个返回错误,内核是无法判断这个错误属于哪个数据包的。
只有当客户端使用connect与服务端建立unp连接时,ICMP不可到达错误才会返还给客户端进程,具体地说是在客户端recv或者read时读取到 这个 ICMP错误。
#include
int main(int argc, char **argv) {
struct sockaddr_in ser;
int fd;
char str[20];
bzero(&ser, sizeof(struct sockaddr_in));
ser.sin_family=AF_INET;
ser.sin_port=htons(9877);
inet_pton(AF_INET, "127.0.0.1", &ser.sin_addr);
fd=socket(AF_INET, SOCK_DGRAM, 0);
if (connect(fd, (struct sockaddr *)&ser, sizeof(struct sockaddr_in))<0)
perror("connect:");
if (sendto(fd, "ok", 3, 0, (struct sockaddr*)&ser, sizeof(struct sockaddr_in))<0)
perror("sendto:");
if (recvfrom(fd, str, 10, 0, NULL, NULL)<0)
perror("recvfrom:");
}

如果服务器未开启的话,那么会有如下输出  recvfrom:: Connection refused

而如果没有connect进行udp连接的话,那么进程就会一直阻塞在recvfrom。。。
阅读(5375) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~