首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

3.5  套接字选项

BSD套接字API提供了许多有用的函数用于发送和接收数据,这些函数的默认行为适合于实现大部分常见的网络功能,但对某些行为进行一些调整也会有助于对实现设计有所改进。setsockopt()函数可用于调整这些行为。

setsockopt()函数允许在网络协议的不同层次对参数进行调整,使用AF_INET地址族时,套接字选项可以针对套接字描述符或者当前所用协议(IPv4UDPTCPICMP协议)的特定方面进行调整。

套接字选项最常用于在套接字层调整参数,包括调整错误处理、数据缓冲、地址处理、端口处理和收发数据的超时参数等。在这些选项当中,套接字层的SO_RCVTIMEO选项经常用来调整read()recv()recvfrom()函数的超时参数。

在默认情况下,read()recv()recvfrom()函数以阻塞方式读取数据,当函数被调用时,将会无限期地等待,直到数据被接收或出现错误。如果在某种实现情况下必须在数据未能及时到达时做出反应,则这种行为是不符合要求的。因此,可以使用SO_RCVTIMEO套接字选项,来设置读取数据的操作在返回调用函数之前的最长等待时间。例3-8说明了如何使用setsockopt()函数设置UDP套接字的SO_RCVTIMEO选项。

3-8  使用setsockopt()设置套接字选项

1   /*

2    * makeudpsock()

3   *

4    *

5   */

6   int makeudpsock (char *dst, unsigned short port)

7   {

8      struct sockaddr_in sin;

9      struct timeval tv;

10     unsigned int taddr = 0;

11     int sock = 0;

12     int ret = 0;

13

14     taddr = inet_addr(targ);

15     if(taddr == INADDR_NONE)

16     {

17              printf("inet_addr() failed.\n");

18              return(-1);

19     }

20

21     sock = socket(AF_INET, SOCK_DGRAM, 0);

22   if(sock < 0)

23     {

24              printf("socket() failed.\n");

25              return(-1);

26     }

27

28     memset(&sin, 0x0, sizeof(sin));

29

30     sin.sin_family = AF_INET;

31     sin.sin_port = htons(port);

32     sin.sin_addr.s_addr = taddr;

33

34     ret = connect(sock, (struct sockaddr *) &sin,

35            sizeof(sin));

36     if(ret < 0)

37     {

38            printf("connect() failed.\n");

39            return(-1);

40     }

41

42     memset(&tv, 0x00, sizeof(tv));

43

44     tv.tv_sec = 10;

45

46     ret = setsockopt(sock, SOL_SOCKET,

47            SO_RCVTIMEO, &tv, sizeof(tv));

48     if(ret < 0)

49     {

50            printf("setsockopt() failed.\n");

51            return(-1);

52     }

53

54     return(sock);

55 }

在此例中,使用socket()connect()函数创建了一个UDP套接字,并将它与一个远程端点关联,然后使用setsockopt()函数设置了这个套接字的接收超时参数,超时参数存放在一个timeval结构中。最后,函数将创建的套接字作为返回值返回。

分析

       7行到第39行,使用socket()connect()函数创建一个 UDP套接字,与前面的示例一样。

       45行和第46行,调用setsockopt()函数。

       传给函数的第1个参数为需要设置选项的套接字描述符。

       2个参数为所设置选项的协议层次,在本例中使用了整型常量SOL_SOCKET,它表示在套接字层设置选项。

       3个参数为套接字选项标志,在本例中为整型常量SO_RCVTIMEO

       函数的第4个和第5个参数是根据第2个与第3个参数即套接字选项的协议层次与选项值确定的。当使用SOL_SOCKETSO_RCVTIMEO选项时,传给第4参数的是一个指向timeval结构的指针,传给第5个参数的是timeval结构的长度(以字节为单位)timeval结构中的tv_secttv_usec成员的值表示从第1个参数处传入的套接字描述符读取数据的超时参数。

 

 

要在IP层设置选项,则使用IPPROTO_IP层次标志代替SOL_SOCKET标志。对于UDP,使用IPPROTO_UDP标志;对于TCP,则使用IPROTO_TCP标志。在sys/socket.hnetinet/in.h两个头文件中定义了其他的套接字层次标志及套接字选项

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论