1. 程式人生 > >Linux下多程序程式設計小例——獲取網絡卡的IP地址

Linux下多程序程式設計小例——獲取網絡卡的IP地址

Linux下多程序程式設計的核心是呼叫fork()系統呼叫用來建立一個新的程序:pid_t   fork(void);  由fork()建立的新程序被稱為子程序。fork()函式被呼叫一次,但有兩次返回。 返回值=0:  子程序              返回值>0:  父程序,返回值為子程序的程序ID。  返回值<0:  出錯 1,子程序可以通過getpid()和getppid()分別獲取自己的程序ID和父程序ID; 2,一個父程序可以有很多個子程序,沒有一個系統呼叫可以獲取所有的子程序ID,所以需要將子程序的ID通過返回值的形式傳遞給父程序。閱讀以下程式碼你需要了解的函式與系統呼叫:dup2()    execl()     wait()      lseek()      pipe(fd)     popen()   strstr()    strchr()   strrchr()    strncpy()     strncpy()   memset()利用多程序程式設計獲取網絡卡eth0的IP地址方法一(利用檔案I/O):

子程序執行ifconfig eth0,將執行的結果輸出重定向到檔案(.ipc.log)中,父程序再從該檔案中讀出ip地址。

/*********************************************************************************
*      Copyright:  (C) 2018 wangtao
*                  All rights reserved.
*
*       Filename:  fork.c
*    Description:  This file
*                 
*        Version:  1.0.0(05/11/2018)
*         Author:  WangTao <
[email protected]
> * ChangeLog: 1, Release initial version on "05/11/2018 06:09:56 PM" * ********************************************************************************/ #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define IPC_FILE ".ipc.log" /******************************************************************************** * Description: * Input Args: * Output Args: * Return Value: ********************************************************************************/ int main (int argc, char **argv) { pid_t pid; int fd = -1; char buf[512]; FILE *fp = NULL; fd = open(IPC_FILE, O_RDWR|O_CREAT|O_TRUNC,0644); //開啟.ipc.log並獲取檔案描述符fd if( fd < 0) { printf("open file '%s' failure: %s\n",IPC_FILE,strerror(errno)); return 0; } pid=fork(); //呼叫fork建立子程序 if(pid <0) { printf("fork() error: %s\n",strerror(errno)); return 0; } else if(pid == 0) //###"子程序"### { dup2(fd,1); //在子程序中,將標準輸出重定向到.ipc.log檔案中(將標準輸出(1)關掉,再將.ipc.log的檔案描述符改為1) execl("/sbin/ifconfig","ifconfig","eth0",NULL); //呼叫execl執行新的程式(命令ifconfig eth0) printf("####haha\n"); //該句不會列印 } else if(pid > 0) //###"父程序"### { int status; wait(&status); //等待子程序退出後,再繼續向下執行 printf("Parent running: child pid[%ld],parent pid[%ld],grandparent pid[%ld]\n",pid,getpid(),getppid()); lseek(fd,0,SEEK_SET); //將檔案偏移量設定為0,不然讀到為空 fp = fdopen(fd,"r"); //將檔案描述符轉換為檔案流 // while( read(fd,buf,sizeof(buf))>0 ) while( fgets(buf,sizeof(buf),fp)>0 ) //將.ipc.log裡的內容一行一行的讀到buf裡 { if( strstr(buf,"inet addr:")) //如果讀到的某一行buf含有關鍵詞"inet addr:",則列印該次buf裡的內容 { printf("buf:%s\n",buf); } } } close(fd); unlink(IPC_FILE); //刪除檔案.ipc.log return 0; } /* ----- End of main() ----- */

程式執行結果:

方法二(利用管道):先建立管道,再建立子程序,這樣父程序和子程序都擁有了管道的讀端與寫端,然後關閉子程序管道讀端,關閉父程序寫端,子程序執行ifconfig eth0,將執行的結果重定向到管道寫端,父程序再從管道讀端裡獲取IP地址。
/*********************************************************************************
*      Copyright:  (C) 2018 wangtao
*                  All rights reserved.
*
*       Filename: fork_pipe.c
*    Description:  This file
*                 
*        Version:  1.0.0(05/11/2018)
*         Author:  WangTao <
[email protected]
> * ChangeLog: 1, Release initial version on "05/11/2018 06:09:56 PM" * ********************************************************************************/ #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include<unistd.h> /******************************************************************************** * Description: * Input Args: * Output Args: * Return Value: ********************************************************************************/ int main (int argc, char **argv) { pid_t pid; int fd[2]; char buf[512]; FILE *fp = NULL; if( pipe(fd)<0 ) //呼叫pipe建立管道, fd引數返回兩個檔案描述符,fd[0]指向管道的讀端,fd[1]指向管道的寫端。fd[1]的輸出是fd[0]的輸入。 { printf("pipe failure: %s\n",strerror(errno)); return -1; } pid=fork(); //呼叫fork建立子程序 if(pid <0) { printf("fork() error: %s\n",strerror(errno)); return 0; } else if(pid == 0) //###"子程序"### { close(fd[0]); //關閉管道讀端 dup2(fd[1],1); //在子程序中,將標準輸出重定向到管道寫端中(將標準輸出(1)關掉,再將管道寫端的檔案描述符改為1) execl("/sbin/ifconfig","ifconfig","eth0",NULL); //呼叫execl執行新的程式(命令ifconfig eth0) printf("####haha\n"); //該句不會列印 } else if(pid > 0) //###"父程序"### { close(fd[1]); //關閉管道寫端 int status; wait(&status); printf("Parent running: child pid[%ld],parent pid[%ld],grandparent pid[%ld]\n",pid,getpid(),getppid()); fp = fdopen(fd[0],"r"); //將檔案描述符轉換為檔案流 while( fgets(buf,sizeof(buf),fp)>0 ) // 將父程序管道讀端裡的內容一行一行的讀到buf裡 { if( strstr(buf,"inet addr:")) { printf("buf:%s\n",buf); } } fclose(fp); } return 0; } /* ----- End of main() ----- */
程式執行結果:
方法三(利用popen函式)推薦:popen()會呼叫fork()產生子程序,然後從子程序中呼叫/bin/sh -c來執行ifconfig eth0    第二個引數“r”代表讀取
/*********************************************************************************
*      Copyright:  (C) 2018 Wang Tao
*                  All rights reserved.
*
*       Filename:  popen.c
*    Description:  This file
*                 
*        Version:  1.0.0(2018年05月12日)
*         Author:  wang tao <[email protected]>
*      ChangeLog:  1, Release initial version on "2018年05月12日 21時14分17秒"
*                 
********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
/********************************************************************************
*  Description:
*   Input Args:
*  Output Args:
* Return Value:
********************************************************************************/
int main (int argc, char **argv)
{
    FILE   *fp;
    char   buf[512];
    char   *p1,*p2,*p3;
    char   ipaddr[16];
    char   netmask[16];

    fp = popen("ifconfig eth0","r");
    if( fp == NULL)
    {
      printf("popen failure: %s\n",strerror(errno));
      return 0;
    }

    while( fgets(buf,sizeof(buf),fp)>0)
    {
      if( (p1=strstr(buf,"inet addr:")) !=NULL)  //p1指向含有"inet addr:"關鍵詞這一行的首地址
      {

          //printf("%s",buf);

          p2=strchr(p1,':');   //p2指向p1行第一個冒號處
          p3=strchr(p2,' ');   //p2指向p2以後第一個空格處
          memset(ipaddr,0,sizeof(ipaddr));
          strncpy(ipaddr,p2+1,p3-p2);      //擷取IP地址到ipaddr陣列中
          printf("IP address: %s\n",ipaddr);
         
          p2=strrchr(p1, ':');   //p2指向p1行最後一個冒號處
          p3=strrchr(p2, '\n');  //p3指向p2以後最後一個換行符處(在p1行中)
          memset(netmask, 0, sizeof(netmask));
          strncpy(netmask, p2+1, p3-p2);    //擷取Mask地址到netmask陣列中
          printf("Netmask address: %s\n", netmask);
      }
    }
    pclose(fp);

    return 0;
} /* ----- End of main() ----- */
程式執行結果:

相關推薦

Linux程序程式設計——獲取IP地址

Linux下多程序程式設計的核心是呼叫fork()系統呼叫用來建立一個新的程序:pid_t   fork(void);  由fork()建立的新程序被稱為子程序。fork()函式被呼叫一次,但有兩次返回。 返回值=0:  子程序              返回值>0: 

LINUX獲取IP地址和MAC地址,子掩碼程式參考

/* mode time:20120727 LINUX下獲取IP地址和MAC地址.程式相關結構體在程式後面。 列印網絡卡的ip地址 子網掩碼 廣播地址 mac地址 環境: [[email protected] temp]# uname -a Linux b

C#之獲取IP地址

有時候不想讀取配置檔案來進行網路監聽,預設把本級所有IP地址監聽一遍,這個時候就需要獲取本級所有IP地址。 如下: string name = Dns.GetHostName(); IPAddress[] ipadrlist = Dns.Get

python獲取IP地址

#!/usr/bin/env python # -*- coding: utf-8 -*- import socket import fcntl import struct def get_ip_address(ifname): s = sock

shell 獲取IP地址掩碼 預設閘道器 廣播地址 MAC地址

# IP地址 ifconfig eth0 | grep "inet addr:" | awk -F " " '{print $2}' | awk -F ":" '{print $2}' # 廣播地址 ifconfig eth0 | grep "inet addr:" |

LinuxLinux 程序程式設計詳解

一.多程序程式的特點    程序是一個具有獨立功能的程式關於某個資料集合的一次可以併發執行的執行活動,是處 於活動狀態的計算機程式。    程序作為構成系統的基本細胞, 不僅是系統內部獨立執行的實體, 而且是獨立競爭資源的基本實體。    程序

linuxC語言獲取MAC地址

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/socket.h&g

linux c/c++按規則獲取ip

linux c/c++按規則獲取網絡卡ip 輸出專案到雲或者輸出給外部客戶,會遇到伺服器多網絡卡多ip的情形,如果有多個應用都需要這個主機ip,而且多應用需要獲取相同的ip,此時可以約定一種規則來獲取相同的ip,比如: 獲得所有網絡卡名,然後對網絡卡名按從小到大排序,查詢最小

linux獲取活動ip地址

1、根據ioctl機制列印當前所有網絡卡 程式碼: #include <sys/ioctl.h> #include <net/if.h> #include <netinet/in.h> #include <arpa/inet.h> #include <

delphi 獲取IP地址列表和Mac地址

1、宣告windows系統的sendarp函式 function sendarp(ipaddr: ulong; temp: dword; ulmacaddr: pointer; ulmacaddrleng: pointer): Dword; StdCall;External

ip addr add和ifconfig的區別看linuxip地址的結構

                今天一個老外在郵件列表上問了一個問題,就是ip addr add和ifconfig的區別,我給他進行了解答,可能因為英語不好吧,解答的很簡單,因此我還是要在這裡詳細說明一下。其實它們之間沒有什麼區別,只 是表述方式不同罷了。如果你非常理解網路協議的原理以及網路的分層架構那麼我想

C#獲取Mac地址

需要using System.Management; /// <summary> /// Get LocalHost MAC Address /// </summary> /// <returns></returns> pub

linux配置IP地址命令詳細介紹及一些常用網路配置命令

Linux命令列下配置IP地址不像圖形介面下那麼方 便,完全需要我們手動配置,下面就給大家介紹幾種配置的方法: 即時生效(重啟後失效): ifconfig eth0 192.168.1.102 netmask 255.255.255.0  //新增IP地址 rout

Shell獲取Mac地址(grep、正則表示式)

#!/bin/bash #brief attain the Mac addr of netcard eth0. #author lee #time 18.08.10 macaddr=`sudo

winPcap獲取網路地址和子掩碼

下面是獲取網路地址(不是IP地址)和子網掩碼的示例,沒時間接著往下做例子了,因為接下來需要在LINUX下面使用libPcap,當然我會貼出程式碼,會linux程式設計的大牛一般都會,所以準確的說是貼給自己的,喜歡玩資料包的朋友自己看官方例子就行 #include<pc

C/S模式---程序程式設計

在單程序下進行socket的程式設計,伺服器通過accept()獲取到客戶端的檔案描述符,並且與該客戶端進行互動。但是實際有兩方面的因素都促使伺服器應該能夠同時與多個客戶端進行互動。 1.listen()函式將已經完成三次握手和即將完成三次握手的客戶端檔案描述符存放到佇列中。 2.在

PX4概念學習(1)——Linux程序執行緒基礎

【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料

Linux程序執行緒基礎

【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料、GPS、PPM訊

linux 程序的同步

      linux 多程序的同步:linux多程序我實現同步操作,操作單個訊號量已經不能實現,對多程序的通訊可以採取訊號集的方式,一個訊號集包含了多個訊號量。 首先通過semget()建立訊號量。例如:semid = semget(SEMKEY,2,0600|IFLAG

linux程序的檔案拷貝與程序相關的一些基礎知識

之前實現了用檔案IO的方式可以實現檔案的拷貝,那麼對於程序而言,我們是否也可以實現呢? 答案是肯定的。 程序資源: 首先我們先回顧一下,程序的執行需要哪些資源呢?其資源包括CPU資源,記憶體資源,當然還有時間片資源,我們都知道程序是有 棧, 堆,  只讀資料段,  資料段(