唯有前进值得敬仰

---等得越久,相聚时越幸福
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

linux socket编程基础3

Posted on 2010-07-09 22:28  绿豆芽33  阅读(634)  评论(0编辑  收藏  举报

我在编程基础2中写的基本上都是tcp的内容,这一节是有关udp的。

本节的主要内容——两个重要函数:recvfrom和sendto。

函数的声明是这样的:

int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
成功时返回发送或接受的数据量,否则均返回-1。

说明:

1.如果需要知道发送者的地址,可以在recvfrom函数中提供空间,若不关心,将from指针和fromlen均值为NULL即可。

2.UDP协议没有为UDP套接字设置发送缓冲区,执行sendto时,直接将数据从用缓冲区拷到系统缓冲区,然后返回,且不保留

 已经发送的内容。UDP套接字只有一个发送缓冲区大小,用来限制发送的最大UDP数据报大小,只要不超过此值,永远不会

 阻塞。

3.允许发送空数据,sendto返回0。

4.UDP协议设置接收缓冲区队列,且有最大限制,超过则丢弃数据报,不发送任何错误。如果缓冲区为空,则recvfrom函数阻塞

 不返回;允许接受空数据报,返回值为0(不同于TCP,收到0表示结束)。

  

UDP协议通信时没有连接通道,任何发送到客户机地址上的数据报将被函数recvfrom接收,不管来自谁。在客户机首次调用函数sendto

之后,它获得了本地端口号,另一个程序如果知道这个端口号,也可以向客户机发送数据报,如何才能避免呢?解决的方法就是客户机调

函数connect。UDP套接字上调用函数connect不会产生3次握手过程,仅在该套接字中记录通信另一方的IP地址和端口号,然后函数返

回。调用了connect的UDP套接字称为连接UDP套接字。这样,连接套接字具有一些特点:

1.发送UDP数据报时不用指定服务器地址;

2.只能接收来自指定服务器的数据报;[尤其是当UDP客户机只与一个服务器通信时,最好调用connect]

3.客户机可以接收到异步错误,并且与其他UNIX系统兼容。

4.UDP套接字允许对一个套接字多次调用函数connect,TCP套接字只允许对一个套接字调用connect。

  struct sockaddr_in addr1,addr2;

  int udpfd;

  .......

  connect(udpfd,(struct sockaddr*)&addr1,sizeof(addr1));

  .......

  connect(udpfd,(struct sockaddr*)&addr2,sizeof(addr2));

  .......

  UDP套接字断开连接的操作与TCP不同,后者使用close,前者只要调用connect与它的地址断开。一般使用Posix定义的一个

特殊套接字地址来调用函数connect,该套接字的协议簇为AF_UNSPEC。

  struct sockaddr_in addr;

  int sockfd;

  .......

  addr.sin_family=AF_UNSPEC;

  .......

  connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));

 这个函数调用以错误返回,错误类型为EAFNOSUPPORT,表示UDP协议不支持AF_UNSPEC类型的套接字地址,于是将这个连接

  UDP套接字记录的地址信息消除,正好。