ioctl 获取本机网卡ip地址 | socket()

来源:互联网 发布:不用网络的单机跳棋 编辑:程序博客网 时间:2024/04/28 13:36
科学尊敬事实,不克不及胡乱编造来由来附会一部学说。
#include <string.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>int main(){    int inet_sock;    struct ifreq ifr;    inet_sock = socket(AF_INET, SOCK_DGRAM, 0);     //eth0为接口到名称    strcpy(ifr.ifr_name, "eth1");    //SIOCGIFADDR标记代表获取接口地址    if (ioctl(inet_sock, SIOCGIFADDR, &ifr) ==  0)          perror("ioctl");    printf("%s",inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));    return 0;}

在一个高贵的目标的支撑下,不绝地工作。即使慢,也必然会获获成功。---------------------------------------------------------------------

ifreq布局定义在/usr/include/net/if.h,用来设备ip地址,激活接口,设备MTU等接口信息的。
此中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。
ifreq包含在ifconf布局中。而ifconf布局凡是是用来保存所有接口的信息的。

----------------------------------------------------------------------------------------------------------

用ioctl获得本地ip地址时要用到两个布局体ifconf和ifreq,它们对于大多半人
来说都是斗劲陌生的,这里给大师一种斗劲简单的懂得办法,当然只一种帮助
懂得的办法,在描述中可能会有一些处所与真实定义有所进出,仅供参考.

起首先熟悉一下ifconf和ifreq:

//ifconf凡是是用来保存所有接口信息的
//if.h
struct ifconf 
{
    int    ifc_len;            /* size of buffer    */
    union 
    {
        char *ifcu_buf;                        /* input  user->kernel*/
        struct ifreq *ifcu_req;        /* return  kernel->user*/
    } ifc_ifcu;
};
#define    ifc_buf    ifc_ifcu.ifcu_buf        /* buffer address    */
#define    ifc_req    ifc_ifcu.ifcu_req        /* array of structures    */
 
//ifreq用来保存某个接口的信息
//if.h
struct ifreq {
    char ifr_name[IFNAMSIZ];
    union {
        struct sockaddr ifru_addr;
        struct sockaddr ifru_dstaddr;
        struct sockaddr ifru_broadaddr;
        short ifru_flags;
        int ifru_metric;
        caddr_t ifru_data;
    } ifr_ifru;
};
#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.ifru_broadaddr

 

上边这两个布局看起来斗劲错杂,我们如今把它们简单化一些:
比如说如今我们向实现获得本地IP的功能。

我们的做法是:
1. 先经由过程ioctl获得本地所有接口的信息,并保存在ifconf中
2. 再从ifconf中取出每一个ifreq中默示ip地址的信息

具体应用时我们可以认为ifconf就有两个成员:
ifc_len 和 ifc_buf,
如图一所示:    

  

ifc_len:默示用来存放所有接口信息的缓冲区长度
ifc_buf:默示存放接口信息的缓冲区

所以我们须要在法度开端时对ifconf的ifc_led和ifc_buf进行初始化
接下来应用ioctl获取所有接口信息,完成后ifc_len内存放实际获得的借口信息总长度
并且信息被存放在ifc_buf中。

如下图示:(假设读到两个接口信息)

   

 

接下来我们只须要从一个一个的接口信息获取ip地址信息即可。

下面有一个简单的参考:

#include 
#include 
#include 
#include 
#include in.h>
#include <string.h>
#include if.h>
#include 
 
int main()
{
    int i=0;
    int sockfd;
  struct ifconf ifconf;
  unsigned char buf[512];
  struct ifreq *ifreq;
  
  //初始化ifconf
  ifconf.ifc_len = 512;
  ifconf.ifc_buf = buf;
  
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0)
    {
        perror("socket");
        exit(1);
    }  
  ioctl(sockfd, SIOCGIFCONF, &ifconf);    //获取所有接口信息
  
  //接下来一个一个的获取IP地址
  ifreq = (struct ifreq*)buf;  
  for(i=(ifconf.ifc_len/sizeof(struct ifreq)); i>0; i--)
  {
//      if(ifreq->ifr_flags == AF_INET){            //for ipv4
          printf("name = [%s]", ifreq->ifr_name);
      printf("local addr = [%s]", 
                      inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr));
      ifreq++;
//  }
  }
    return 0;
}
 
此办法仅供参考,也实用于获取其他信息。

--------------------------------------------------------------------------------------------------------------------------------------------------------------李四光

简述:
创建一个套接口。
#include <winsock.h>
SOCKET PASCAL FAR socket( int af, int type, int protocol);
af:一个地址描述。今朝仅支撑AF_INET格局,也就是说ARPA Internet地址格局。
type:新套接口的类型描述。
protocol:套接口所用的和谈。如调用者不想指定,可用0。

注释


  socket()函数用于按照指定的地址族、数据类型和和谈来分派一个套接口的描述字及其所用的资料。若是和谈protocol未指定(便是0),则应用缺省的连接体式格式。
对于应用一给定地址族的某一特定套接口,只支撑一种和谈。但地址族可设为AF_UNSPEC(未指定),如许的话和谈参数就要指定了。和谈号特定于进行通信的“通信域”。支撑下述类型描述:
类型 申明
SOCK_STREAM 供给有序的、靠得住的、双向的和基于连接的字节俭,应用带外数据传送机制,为Internet地址族应用TCP。
SOCK_DGRAM 支撑无连接的、不成靠的和应用固定大小(凡是很小)缓冲区的数据报办事,为Internet地址族应用UDP。
SOCK_STREAM类型的套接口为全双向的字节俭。对于流类套接口,在接管或发送数据前必须处于已连接状况。用connect()调用建树与另一套接口的连接,连接成功后,即可用send()和recv()传送数据。当会话停止后,调用closesocket()。带外数据按照规定用send()和recv()来接管。
实现SOCK_STREAM类型套接口的通信和谈包管数据不会丧失也不会反复。若是终端和谈有缓冲区空间,且数据不克不及在一按时候成功发送,则认为连接中断,厥后续的调用也将以WSAETIMEOUT错误返回。
SOCK_DGRAM类型套接口容许应用sendto()和recv()从随便率性端口发送或接管数据报。若是如许一个套接口用connect()与一个指定端口连接,则可用send()和recv()与该端口进行数据报的发送与接管。

返回值


  若无错误产生,socket()返回引用新套接口的描述字。不然的话,返回INVAID_SOCKET错误,应用法度可经由过程WSAGetLastError()获取响应错误代码。
错误代码:
WSANOTINITIALISED:在应用此API之前应起首成功地调用WSAStartup()。
WSAENETDOWN:WINDOWS套接话柄现检测到收集子体系失效。
WSAEAFNOSUPPORT:不支撑指定的地址族。
WSAEINPROGRESS:一个梗阻的WINDOWS套接口调用正在运行中。
WSAEMFILE:无可用文件描述字。
WSAENOBUFS:无可用缓冲区,无法创建套接口。
WSAEPROTONOSUPPORT:不支撑指定的和谈。
WSAEPROTOTYPE:指定的和谈不实用于本套接口。
WSAESOCKTNOSUPPORT:本地址族中不支撑该类型套接口。

拜见


  accept(), bind(), connect(), getsockname(), getsockopt(), setsockopt(), listen(), recv(), recv(), (), send(), sendto(), shutdown(), ioctlsocket().4.2 数据库例程
socket()
函数原型:
SOCKET WSAAPI  socket(
int af,
int type,
int protocol
);
该函数及参数定义包含在winsock2.h头文件中,在MSDN中查不到具体参数。
参数选项及定义:
地址族af:(常用AF_INET实现TCP/UDP和谈)
#define AF_UNSPEC       0               /* unspecified */
#define AF_UNIX         1               /* local to host (pipes, portals) */
#define AF_INET         2               /* internetwork: UDP, TCP, etc. */
#define AF_IMPLINK      3               /* arpanet imp addresses */
#define AF_PUP          4               /* pup protocols: e.g. BSP */
#define AF_CHAOS        5               /* mit CHAOS protocols */
#define AF_NS           6               /* XEROX NS protocols */
#define AF_IPX          AF_NS           /* IPX protocols: IPX, SPX, etc. */
#define AF_ISO          7               /* ISO protocols */
#define AF_OSI          AF_ISO          /* OSI is ISO */
#define AF_ECMA         8               /* european computer manufacturers */
#define AF_DATAKIT      9               /* datakit protocols */
#define AF_CCITT        10              /* CCITT protocols, X.25 etc */
#define AF_SNA          11              /* IBM SNA */
#define AF_DECnet       12              /* DECnet */
#define AF_DLI          13              /* Direct data link interface */
#define AF_LAT          14              /* LAT */
#define AF_HYLINK       15              /* NSC Hyperchannel */
#define AF_APPLETALK    16              /* AppleTalk */
#define AF_NETBIOS      17              /* NetBios-style addresses */
#define AF_VOICEVIEW    18              /* VoiceView */
#define AF_FIREFOX      19              /* Protocols Firefox */
#define AF_UNKNOWN1     20              /* Somebody is using this! */
#define AF_BAN          21              /* Banyan */
#define AF_ATM          22              /* Native ATM Services */
#define AF_INET6        23              /* Internetwork Version 6 */
#define AF_CLUSTER      24              /* Microsoft Wolfpack */
#define AF_12844        25              /* IEEE 1284.4 WG AF */
套接字类型type:
#define SOCK_STREAM     1               /* stream socket */
#define SOCK_DGRAM      2               /* datagram socket */
#define SOCK_RAW        3               /* raw-protocol interface */
#define SOCK_RDM        4               /* reliably-delivered message */
#define SOCK_SEQPACKET  5               /* sequenced packet stream */
和谈类型protocol:
#define IPPROTO_IP              0               /* dummy for IP */
#define IPPROTO_ICMP            1               /* control message protocol */
#define IPPROTO_IGMP            2               /* internet group management protocol */
#define IPPROTO_GGP             3               /* gateway^2 (deprecated) */
#define IPPROTO_TCP             6               /* tcp */
#define IPPROTO_PUP             12              /* pup */
#define IPPROTO_UDP             17              /* user datagram protocol */
#define IPPROTO_IDP             22              /* xns idp */
原创粉丝点击