ioctl在socket中的一些用法及示例

简介: ioctl在socket中的一些用法及示例 函数 : ioctl(int fd, int request, void * arg)定义 : 功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段.
ioctl在socket中的一些用法及示例

函数 : ioctl(int fd, int request, void * arg)
定义 :
功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段.
参数 : int  fd      文件句柄. 用于socket时, 是socket套接字.
       int  request 函数定义的所有操作. 关于socket的操作, 定义在文件中.
       void *arg    指针的类型依赖于request参数.
 
以下表格从网上收集了request - arg指针类型的对应关系

类别

Request

说明

数据类型



SIOCATMARK
SIOCSPGRP
SIOCGPGRP

是否位于带外标记
设置套接口的进程ID 或进程组ID
获取套接口的进程ID 或进程组ID

int
int
int


FIONBIN
FIOASYNC
FIONREAD
FIOSETOWN
FIOGETOWN

设置/ 清除非阻塞I/O 标志
设置/ 清除信号驱动异步I/O 标志
获取接收缓存区中的字节数
设置文件的进程ID 或进程组ID
获取文件的进程ID 或进程组ID

int
int
int
int
int


SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
SIOCxxx

获取所有接口的清单
设置接口地址
获取接口地址
设置接口标志
获取接口标志
设置点到点地址
获取点到点地址
获取广播地址
设置广播地址
获取子网掩码
设置子网掩码
获取接口的测度
设置接口的测度
获取接口MTU
(还有很多取决于系统的实现)

struct ifconf
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq

ARP

SIOCSARP
SIOCGARP
SIOCDARP

创建/ 修改ARP 表项
获取ARP 表项
删除ARP 表项

struct arpreq
struct arpreq
struct arpreq


SIOCADDRT
SIOCDELRT

增加路径
删除路径

struct rtentry
struct rtentry

I_xxx

 

 

socket最常用到的结构体: struct ifreq 定义在.(包括struct ifconf/ifr_flags等的定义)

 

一、获取

以下例程通过ioctl获取设备"eth0"的IP/掩码/硬件址

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "string.h"

  4. #include "net/if.h"
  5. #include "arpa/inet.h"
  6. #include "linux/sockios.h"

  7. int main(int argc,char *argv[])
  8. {
  9.     struct sockaddr_in *addr;
  10.     struct ifreq ifr;
  11.     char*address;
  12.     int sockfd;

  13.     char *name = "eth0";
  14.     if( strlen(name) >= IFNAMSIZ)
  15.         printf("device name is error.\n"), exit(0);
  16.         
  17.     strcpy( ifr.ifr_name, name);
  18.         
  19.     sockfd = socket(AF_INET,SOCK_DGRAM,0);

  20.     //get inet addr
  21.     if( ioctl( sockfd, SIOCGIFADDR, &ifr) == -1)
  22.         printf("ioctl error.\n"), exit(0);

  23.     addr = (struct sockaddr_in *)&(ifr.ifr_addr);
  24.     address = inet_ntoa(addr->sin_addr);

  25.     printf("inet addr: %s\n",address);

  26.     //get Mask
  27.     if( ioctl( sockfd, SIOCGIFNETMASK, &ifr) == -1)
  28.         printf("ioctl error.\n"), exit(0);

  29.     addr = (struct sockaddr_in *)&ifr.ifr_addr;
  30.     address = inet_ntoa(addr->sin_addr);

  31.     printf("Mask: %s\n",address);

  32.     //get HWaddr
  33.     u_int8_t hd[6];
  34.     if(ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1)
  35.         printf("hwaddr error.\n"), exit(0);

  36.     memcpy( hd, ifr.ifr_hwaddr.sa_data, sizeof(hd));
  37.     printf("HWaddr: %02X:%02X:%02X:%02X:%02X:%02X\n", hd[0], hd[1], hd[2], hd[3], hd[4], hd[5]);
  38.     
  39.     exit(0);
  40. }


 二、设置

以下例程设置eth0的IP地址.

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "string.h"

  4. #include "net/if.h"
  5. #include "arpa/inet.h"
  6. #include "linux/sockios.h"

  7. int main(int argc,char *argv[])
  8. {
  9.     char *dev = "eth0";
  10.     char *ip = "192.168.1.252";
  11.     
  12.     struct ifreq ifr;
  13.     if( strlen(dev) >= IFNAMSIZ)
  14.         printf("device name error.\n"), exit(0);
  15.     else
  16.         strcpy( ifr.ifr_name, dev);
  17.     
  18.     int sockfd = socket(AF_INET,SOCK_DGRAM,0);

  19.     //get inet addr
  20.     if( ioctl( sockfd, SIOCGIFADDR, &ifr) == -1)
  21.         printf("ioctl error.\n"), exit(0);
  22.     
  23.     struct sockaddr_in *addr = (struct sockaddr_in *)&(ifr.ifr_addr);
  24.     char * address = inet_ntoa(addr->sin_addr);

  25.     printf("current inet addr: %s\n",address);

  26.     //set inet addr
  27.     struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);

  28.     p->sin_family = AF_INET;
  29.     inet_aton( ip, &(p->sin_addr));

  30.     if( ioctl( sockfd, SIOCSIFADDR, &ifr) == -1)
  31.      printf("ioctl error.\n"), exit(0);
  32.     else    
  33.         printf("change inet addr to: %s\n", ip);

  34.     //any OS need active dev.
  35.     /*ifr.ifr_flags |= IFF_UP;
  36.     if( ioctl( sockfd, SIOCSIFFLAGS, &ifr) == -1)
  37.         printf("active fault.\n"), exit(0);
  38.     else
  39.         printf("%s[%s] is working...\n", dev, ip);
  40.     */
  41.         
  42.     close(sockfd);
  43.     exit(1);
  44.     //end
  45. }

屏蔽的代码用于设置IP后, 激活新设置. 多数系统不需要这步操作.
而且这步仅作演示. 真实使用的时候, 至少应该
1. 获取当前ifr.ifr_flags
2. ifr.ifr_flags |= IFF_UP;

以上是ioctl的一些示例, 实战中灵活使用、举一反三.

 

 

相关文章
|
安全 网络协议 Java
Thread类的用法 && 线程安全 && 多线程代码案例 && 文件操作和 IO && 网络原理初识 &&UDP socket
Thread类的用法 && 线程安全 && 多线程代码案例 && 文件操作和 IO && 网络原理初识 &&UDP socket
72 0
|
网络协议 算法
|
算法 Windows 数据安全/隐私保护
setsockopt 设置socket 详细用法
1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL)); 2.
1464 0
|
2月前
|
网络协议 测试技术 网络安全
Python编程-Socket网络编程
Python编程-Socket网络编程
26 0
|
5月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
60 4
|
5月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
35 3
|
5月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
67 2
|
5月前
|
网络协议 程序员 视频直播

热门文章

最新文章