Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300318
  • 博文数量: 35
  • 博客积分: 836
  • 博客等级: 准尉
  • 技术积分: 678
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-07 20:11
文章分类

全部博文(35)

文章存档

2013年(1)

2012年(24)

2011年(10)

分类: LINUX

2012-03-11 02:09:57

在Linux 网络编程中,有两个函数,

点击(此处)折叠或打开

  1. #include <sys/types.h> /* See NOTES */
  2.        #include <sys/socket.h>

  3.        int getsockopt(int sockfd, int level, int optname,
  4.                       void *optval, socklen_t *optlen);
  5.        int setsockopt(int sockfd, int level, int optname,
  6.                       const void *optval, socklen_t optlen);
以上两个函数使用来设置以及获得socket中的一些选项。这两个函数的参数中的scokfd制定的是需要操作的socket,而optname指定的是操作所面向的选项名称,optval以及optlen则是对所获的内容/所设置内容的一个描述。而level之前则一直没有办法理解,今天在看了一段代码之后就豁然开朗了。

level在通常的时候使用SOL_SOCKET用来制定对应的对应的相关操作,如之前博客所涉及到的sndbuf大小。

今天在看UDP实现的时候发现UDP中对应setsockopt对应的代码如下:

点击(此处)折叠或打开

  1. int udp_setsockopt(struct sock *sk, int level, int optname,
  2.          char __user *optval, unsigned int optlen)
  3. {
  4.     if (level == SOL_UDP || level == SOL_UDPLITE)
  5.         return udp_lib_setsockopt(sk, level, optname, optval, optlen,
  6.                      udp_push_pending_frames);
  7.     return ip_setsockopt(sk, level, optname, optval, optlen);
  8. }
通过此段代码我就明白了level的意思,当level是属于SOL_UDP时,则进行UDP协议专属的一些设置属性操作,如果不是的话,那么则应当是UDP所依赖的IP协议,则调用ip_setsockopt。

通过了level这个参数,使用统一个接口函数能够设置不同协议的属性。当设置为SOL_SOCKET时表示的是socket通用的属性,那么不需要涉及具体的协议,可以直接搞定。如果涉及到具体的协议,如TCP/UDP则需要指定level为对应的值。这个可以通过setsockopt的内核中系统调用的入口能够看到。

点击(此处)折叠或打开

  1. SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  2.         char __user *, optval, int, optlen)
  3. {
  4.     int err, fput_needed;
  5.     struct socket *sock;

  6.     if (optlen < 0)
  7.         return -EINVAL;

  8.     sock = sockfd_lookup_light(fd, &err, &fput_needed);
  9.     if (sock != NULL) {
  10.         err = security_socket_setsockopt(sock, level, optname);
  11.         if (err)
  12.             goto out_put;

  13.         if (level == SOL_SOCKET)
  14.             err =
  15.              sock_setsockopt(sock, level, optname, optval,
  16.                      optlen);
  17.         else
  18.             err =
  19.              sock->ops->setsockopt(sock, level, optname, optval,
  20.                          optlen);
  21. out_put:
  22.         fput_light(sock->file, fput_needed);
  23.     }
  24.     return err;
  25. }
这个函数中,首先是根据level是否等于SOL_SOCKET来确定对应的服务函数,如果为SOL_SOCKET那么直接调用sock_setsockopt函数来解决,因为在struct sock这个层次就能够解决此问题,如果不是这个level那么说明需要对应具体的协议,那么就调用对应协议的setsockopt实现来实现。

阅读(2663) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~