【原创】《Linux高级程序设计》杨宗德著 - TCP高级应用 - socket文件描述符属性控制


【原创】《Linux高级程序设计》杨宗德著 - TCP高级应用 - socket文件描述符属性控制


1. getsockopt和setsockopt修改socket属性

int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen) 
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen) 
level指定控制套接字的层次.可以取三种值: 
1)SOL_SOCKET:通用套接字选项. 
2)IPPROTO_IP:IP选项. 
3)IPPROTO_TCP:TCP选项. 
对应的optname详细说明 
optname指定控制的方式(选项的名称). 
选项名称 说明 数据类型 
======================================================================
SOL_SOCKET 
SO_BROADCAST 允许发送广播数据 int 
SO_DEBUG 允许调试 int 
SO_DONTROUTE 不查找路由 int 
SO_ERROR 获得套接字错误 int 
SO_KEEPALIVE 保持连接 int 
SO_LINGER 延迟关
SO_OOBINLINE 带外数据放入正常数据流 int 
SO_RCVBUF 接收缓冲区大小 int 
SO_SNDBUF 发送缓冲区大小 int 
SO_RCVLOWAT 接收缓冲区下限 int 
SO_SNDLOWAT 发送缓冲区下限 int 
SO_RCVTIMEO 接收超时 struct timeval 
SO_SNDTIMEO 发送超时 struct timeval 
SO_REUSERADDR 允许重用本地地址和端口 int 
SO_TYPE 获得套接字类型 int 
SO_BSDCOMPAT 与BSD系统兼容 int

IPPROTO_IP 
IP_HDRINCL 在数据包中包含IP首部 int 
IP_OPTINOS IP首部选项 int 
IP_TOS 服务类型 
IP_TTL 生存时间 int

IPPRO_TCP 
TCP_MAXSEG TCP最大数据段的大小 int 
TCP_NODELAY 不使用Nagle算法 int

optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换 ,有时是套接字选项.ON或者OFF等

2. fcntl控制socket

status = fcntl (hand, option, mode ) ;
上述fcntl函数调用中,各参数定义如下:
    handle:已打开的文件句柄。
    option:一般可以是下列两种值:
        F_GETFL:表示读取文件状态值。
       F_SETFL:表示设置文件状态值。
(注意:F_GETFL和F_SETFL都被定义在fcntl.h)
    mode:如果optipn是F_GETFL,则这个参数值可以是任意值。如果是F_SETFL,则参数值可以是下列值:
 O_WRONLY:将文件设置成只写状态。
O_RDWR:   将文件设置成读写状态。
O_RDONLY:将文件设置成只读状态。
status:函数会将调用结果赋给status,如运行失败,则status的值会被设成-1。

控制socket为非阻塞方式 

设置socket为信号驱动型socket,其将使socket在状态发生改变时产生SIGIO信号。 

(3)使用F_SETOWN选项设置socket的拥有者以接收SIGIO和SIGURG 信号。如下示例:
fcntl(socket, F_SETOWN, getpid());
(4)使用F_GETOWN选项获取某socket的拥有者。
fcntl(socket, F_GETOWN, getpid());

3. ioctl控制文件描述符 

#include <stropts.h>
int ioctl(int fildes, int request, ... /* arg */);
ioctl可以控制所有的文件描述符的情况,这里介绍一下控制套接字的选项. 
ioctl的控制选项 
SIOCATMARK 是否到达带外标记 int 
FIOASYNC 异步输入/输出标志 int 
FIONREAD 缓冲区可读的字节数 int
详细的选项请用 man ioctl_list 查看.

ioctl示例代码

ioctl获取本地IP地址 

#include <net/if.h>

#include <sys/ioctl.h>

#include <string.h>

#include <stdio.h>

#include <sys/socket.h>

#include <arpa/inet.h>



int main()

{

        int inet_sock;

        struct ifreq ifr;

        inet_sock = socket(AF_INET, SOCK_DGRAM, 0);

        strcpy(ifr.ifr_name, "eth0");

        if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)

                perror("ioctl");

        printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));

}
运行结果

$ ./ioctl_getaddr 
172.18.229.62<span style="color:#339999;">
</span>

ioctl获取指定接口的MAC地址

#include<stdlib.h>

#include<stdio.h>

#include<string.h>

#include<sys/ioctl.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<net/if.h>

// argv[0] portname ,such as argv[0] eth0

int main(int argc, char *argv[])

{

    int i;

   struct ifreq ifreq;

    int sock;

    char mac[32];

    

    if((sock=socket(AF_INET,SOCK_STREAM,0))<0)

    {

        perror("error");

        exit(EXIT_FAILURE);

    }

    strcpy(ifreq.ifr_name,argv[1]);

    if(ioctl(sock,SIOCGIFHWADDR,&ifreq)<0)

    {

        perror("error:");

        exit(EXIT_FAILURE);

    }

    for (i=0; i<6; i++)

        sprintf(mac+3*i, "%02x:", (unsigned char)ifreq.ifr_hwaddr.sa_data[i]);

    mac[17]='\0';

    printf("mac addr is: %s\n", mac);

    return 0;

}
运行结果

$ ./get_port_mac eth0
mac addr is: 00:0c:29:xx:xx:xx

原文链接

http://blog.csdn.net/geng823/article/details/41773735


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux高级程序设计》是由杨宗德和吕光宏合著的一本经典编程书籍。该书具有以下特点和价值: 首先,该书全面而深入地介绍了Linux高级编程概念和技术,涵盖了Linux系统编程的方方面面。读者可以从中学习到Linux程序设计的基本知识,如进程管理、线程编程、文件操作、内存管理等,同时也可以学习到高级技术,如网络编程、信号处理、套接字编程等。 其次,该书注重实践与理论的结合,通过丰富的代码示例和实际案例,帮助读者加深对Linux编程的理解和应用。这些示例和案例设计合理,代码规范,可以帮助读者快速掌握各种编程技术,并提供了实际项目开发经验。 再次,该书系统性强,内容全面而深入。从系统调用、文件系统到网络编程、进程间通信,从基础知识到高级技术,涵盖了Linux程序设计的方方面面。由浅入深的组织结构和清晰的逻辑思路,使得读者可以循序渐进地学习,并可以根据自身需求选择阅读的内容。 最后,该书是一本经典且广泛应用于教育和实践的优秀教材。它以其权威性和实用性备受好评,成为许多大学和学院的Linux编程教材。除此之外,该书也适合有一定编程基础的工程师和开发人员自学。 总之,杨宗德和吕光宏的《Linux高级程序设计》是一本经典而实用的Linux编程教材,内容丰富、全面,适合初学者和有一定基础的程序员学习和参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值