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的一些示例, 实战中灵活使用、举一反三.

 

 

目录
相关文章
|
3月前
|
Java Android开发
Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。
【6月更文挑战第23天】 Java Socket编程示例:服务器开启在8080端口监听,接收客户端连接并打印消息。客户端连接服务器,发送"Hello, Server!"后关闭。注意Android中需避免主线程进行网络操作。
68 4
|
4月前
|
网络协议 NoSQL Linux
非阻塞socket网络编程之数据收发完整代码示例
非阻塞socket网络编程之数据收发完整代码示例
|
网络协议 Linux API
Android C++ 系列:Linux Socket 编程(三)CS 模型示例
服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于 监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服 务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK 段,服务器收到后从accept()返回。
152 0
|
JavaScript
node.js: socket.io服务端和客户端交互示例
node.js: socket.io服务端和客户端交互示例
308 0
node.js: socket.io服务端和客户端交互示例
|
网络协议 图形学
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
664 0
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
|
Java
简单的java socket 示例
一、搭建服务器端 a)、创建ServerSocket对象绑定监听端口。 b)、通过accept()方法监听客户端的请求。 c)、建立连接后,通过输入输出流读取客户端发送的请求信息。 d)、通过输出流向客户端发送请求信息。
754 0
|
Java Linux 缓存
Java基于Socket文件传输示例
采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度。 1.服务器端 package sterning; import java.io.BufferedInputStream; import java.
888 0
|
2月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
27 4