Qt 嵌入式 利用wpa_supplicant编写WIFI、有线网络管理器

  • HNEthManager

嵌入式linux系统中没有内置自动化程度高的管理程序,这个程序就完成根据有线插拔来判断是否启用无线的功能。

HNEthManager

hnethmanager.h

#ifndef HNETHMANAGER_H
#define HNETHMANAGER_H

#include <QObject>
#include <QTimer>
#include <QList>
#include "HNDefine.h"
#include <qthread.h>
#include "HNDefine.h"

class HNNetworkClearThread : public QThread
{
    Q_OBJECT
public:
    HNNetworkClearThread(QObject* parent = 0) : QThread(parent) {
    }
signals:
    void cleared();
    void notcleared();

    // QThread interface
protected:
    void run();
};

class HNDhcpThread : public QThread
{
    Q_OBJECT
public:
    HNDhcpThread(QObject* parent = 0) : QThread(parent) {
    }
    void setnet(QString eth = "eth0") {net=eth;}
signals:
    void passed(QString);
    // QThread interface
protected:
    void run();
private:
    QString net;
};

// thread unsafe
class HNEthManager : public QObject
{
    Q_OBJECT
public:
    static HNEthManager *Instance(QObject* parent = 0);

    QList<TWifi>& wifiList() { return m_wifiList; }
    inline TWifi currentWifi(){ return m_curWifi; }
    bool setCurrentWifi(QString bssid_mac, QString password = "");
    void setRefresh(bool ref = true) { ref ? m_workTimer->start(5000) : m_workTimer->stop(); }
    void setDHCP(bool bUse = false) { m_bUseDHCP = bUse; }
    void configIPAddress(QString ip, QString mask, QString gw, QString dns);
    QString currentNetName();
    QTimer* workTimer() { return m_workTimer; }
    void saveAddr(QString ip, QString mask, QString gw, QString dns);
    void getAddr(QString& ip, QString& mask, QString& gw, QString& dns);

signals:
    //没有配置就会发送这个信号
    void sigScanning();
    //断开连接的状态
    void sigDisConnected();
    //正在连接的状态
    void sigConnecting();
    //连接成功的状态
    void sigConnected();
    //Wifi列表更新 之上状态改变会影响list中wifi的标志位。
    void sigRefreshed();
    //Wifi状态改变
    void sigStatusChanged(QString status);
    //有线连接上
    void sigLanConnected();
    //有线断开
    void sigLanDisConnected();
    //网络线路连接上
    void sigNetworkClear();
    //网络线路断开
    void sigNetworkNotClear();

private slots:
    void refreshWifiList();
    void refreshWifiStatus();
    void checkLanConnection();
    void DhcpPassed(QString netname);
    void checkNetworkClear();

private:
    explicit HNEthManager(QObject *parent = 0);
    void readStatus();
    void restoreWifi();
    bool restartWifi();
    void saveScript();
    void config();

signals:

public slots:
private:
    static HNEthManager* _instance;
    QTimer* m_workTimer;
    QList<TWifi> m_wifiList;
    TWifi m_curWifi;
    bool m_bUseDHCP;
    QString m_netName;
    HNDhcpThread* m_thread;
    HNNetworkClearThread* m_clearThread;
    QString m_status;
};

#endif // HNETHMANAGER_H

hnethmanager.cpp

#include "HNEthManager.h"
#include "hnlinux.h"
#include "HNDefine.h"

HNEthManager* HNEthManager::_instance = NULL;

HNEthManager *HNEthManager::Instance(QObject *parent)
{
    if(_instance)
        return _instance;
    _instance = new HNEthManager(parent);
    return _instance;
}

bool HNEthManager::setCurrentWifi(QString bssid_mac, QString password)
{
    for(QList<TWifi>::Iterator it = m_wifiList.begin();
        it != m_wifiList.end(); it++)
    {
        TWifi wifi = *it;
        if(bssid_mac == wifi[ESSID_BSSID])
        {
            m_status = "";
            m_curWifi = wifi;
            m_curWifi[ESSID_PASS] = password;
            break;
        }
    }

    restoreWifi();

    if(!restartWifi())
        return false;

    return true;
}

void HNEthManager::configIPAddress(QString ip, QString mask, QString gw, QString dns)
{
    saveAddr(ip, mask, gw, dns);
    saveScript();
    config();
}

QString HNEthManager::currentNetName()
{
    if("eth0" == m_netName)
        return "Wired Lan";
    if("wlan0" == m_netName)
        if("COMPLETED" == m_status)
            return m_curWifi[ESSID_NAME];
    return "";
}

void HNEthManager::readStatus()
{
    //从 status 中读取
    char result[MAX_LEN];
    char key[MAX_LEN]; //设置一个合适的长度,以存储每一行输出
    char value[MAX_LEN]; //设置一个合适的长度,以存储每一行输出

    bzero(result, MAX_LEN);
    bzero(key, MAX_LEN);
    bzero(value, MAX_LEN);
    FILE *pp = popen("wpa_cli -iwlan0 status", "r"); //建立管道
    if (!pp)
        return;
    while( fgets(result, sizeof(result), pp) != NULL)
    {
        sscanf(result, "%[^=]=%s", key, value);
        //如果这里不用QString包含,会对比地址
        if(QString("wpa_state") == QString(key)) {
            m_curWifi[ESSID_STATUS] = value;
        } else if(QString("bssid") == QString(key)) {
            m_curWifi[ESSID_BSSID] = value;
        } else if(QString("ssid") == QString(key)) {
            m_curWifi[ESSID_NAME] = value;
        }
    }
    pclose(pp);

    return;
}

void HNEthManager::refreshWifiList()
{
    static int scanid = 0;
    if(scanid == 12)
        scanid = 0, system("wpa_cli -iwlan0 scan");
    scanid ++;

    FILE *pp = popen("wpa_cli -iwlan0 scan_r", "r"); //建立管道
    if (!pp)
        return;

    char cmdresult[MAX_LEN]; //设置一个合适的长度,以存储每一行输出
    fgets(cmdresult, sizeof(cmdresult), pp) ; //""

    char bssid[MAX_PATH];
    char frequency[MAX_PATH];
    char signal[MAX_PATH];
    char flag[MAX_PATH];
    char ssid[MAX_PATH];

    m_wifiList.clear();

    while( fgets(cmdresult, sizeof(cmdresult), pp) != NULL)
    {
        sscanf(cmdresult, "%s\t%s\t%s\t%s\t%s\n", bssid, frequency, signal, flag, ssid);

        TWifi wifi;
        wifi[ESSID_NAME] = ssid;
        if( strstr(flag, "WPA"))
            wifi[ESSID_TYPE] = "WPA";
        else
            wifi[ESSID_TYPE] = "WEP";
        if(strstr(flag, "WPA") || strstr(flag, "WEP"))
            wifi[ESSID_ENCRYP] = "YES";
        else
            wifi[ESSID_ENCRYP] = "NO";
        wifi[ESSID_PASS] = "";
        wifi[ESSID_BSSID] = bssid;
        wifi[ESSID_FREQ] = frequency;
        wifi[ESSID_SIGNAL] = signal;
        wifi[ESSID_FLAG] = flag;
        if(wifi[ESSID_BSSID] == m_curWifi[ESSID_BSSID])
            wifi[ESSID_STATUS] = m_curWifi[ESSID_STATUS];
        else
            wifi[ESSID_STATUS] = "";

        m_wifiList.push_back(wifi);

        //pline() << ssid << frequency << signal << flag << bssid << wifi[ESSID_STATUS];
    }

    //pline() << m_wifiList.size();
    pclose(pp); //关闭管道
    emit sigRefreshed();
}

void HNEthManager::refreshWifiStatus()
{
    readStatus();

    if(m_status == m_curWifi[ESSID_STATUS])
        return;

    pline() << m_curWifi[ESSID_BSSID] << m_curWifi[ESSID_NAME] << m_curWifi[ESSID_STATUS];

    m_status = m_curWifi[ESSID_STATUS];
    emit sigStatusChanged(m_status);

    if("COMPLETED" == m_status)
        emit sigConnected();
    else if("SCANNING" == m_status)
        emit sigScanning();
    else if("ASSOCIATING" == m_status)
        emit sigConnecting();
    else if("INACTIVE" == m_status)
        emit sigDisConnected();
    else if("4WAY_HANDSHAKE" == m_status)
        emit sigDisConnected();
    else if("DISCONNECTED" == m_status)
        emit sigDisConnected();
}

void HNEthManager::checkLanConnection()
{
    char cmdbuf[MAX_PATH];
    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出
    bzero(cmdbuf, MAX_PATH);
    bzero(cmdresult, MAX_PATH);
    sprintf(cmdbuf, "cat /sys/class/net/eth0/carrier");
    FILE *pp = popen(cmdbuf, "r"); //建立管道
    fgets(cmdresult, sizeof(cmdresult), pp); //""
    pclose(pp);

    QString netName = m_netName;

    if(strstr(cmdresult, "0"))
        m_netName = "wlan0";
    else
        m_netName = "eth0";

    if(netName != m_netName)
    {
        config();
        if("wlan0" == m_netName)
            emit sigLanDisConnected();
        else
            emit sigLanConnected();
    }

    return;
}

void HNEthManager::DhcpPassed(QString netname)
{
    int sockfd;
    struct ifreq ifr;
    struct sockaddr_in sin;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("socket");
        return;
    }
    strncpy(ifr.ifr_name, netname.toAscii().data(), IFNAMSIZ);
    ifr.ifr_name[IFNAMSIZ - 1] = 0;
    //ip
    if(ioctl(sockfd, SIOCGIFADDR, &ifr) <0)
        perror("ioctl");
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    QString ip = QString(inet_ntoa(sin.sin_addr));
    //mask
    if (ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0)
        perror("ioctl");
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    QString mask = QString(inet_ntoa(sin.sin_addr));
    //mac
    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
        perror("ioctl");
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    QString mac = QString(inet_ntoa(sin.sin_addr));
    close(sockfd);
    //gw
    FILE *fp;
    char buf[MAX_PATH];
    char gateway[MAX_PATH];
    bzero(buf, MAX_PATH);
    bzero(gateway, MAX_PATH);
    fp = popen("ip route", "r");
    while(fgets(buf, sizeof(buf), fp) != NULL)
    {
        if(strstr(buf, "default via"))
        {
            sscanf(buf, "%*s%*s%s", gateway);
            break;
        }
    }
    pclose(fp);
    QString gw = gateway;
    //dns
    QFile file("/etc/resolv.conf");
    file.open(QFile::ReadOnly);
    QByteArray nameserver = file.readLine();
    nameserver[nameserver.size()-1] = ‘\0‘;
    QList<QByteArray> namelist = nameserver.split(‘ ‘);
    QString dns = namelist.size() > 1 ? namelist[1] : gw;
    file.close();

    //pt
    pline() << netname << ip << mask << gw << dns;

    saveAddr(ip, mask, gw, dns);
    saveScript();
}

void HNEthManager::checkNetworkClear()
{
    return;
    m_clearThread->start();
}

HNEthManager::HNEthManager(QObject *parent) :
    QObject(parent)
{
    m_bUseDHCP = false;
    m_clearThread = new HNNetworkClearThread(this);
    connect(m_clearThread, SIGNAL(cleared()), this, SIGNAL(sigNetworkClear()));
    connect(m_clearThread, SIGNAL(notcleared()), this, SIGNAL(sigNetworkNotClear()));
    m_thread = new HNDhcpThread(this);
    connect(m_thread, SIGNAL(passed(QString)), this, SLOT(DhcpPassed(QString)));
    //检查网线
    //搜索热点
    //刷新连接状态
    m_workTimer = new QTimer(this);
    m_workTimer->setSingleShot(false);
    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(refreshWifiList()));
    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(refreshWifiStatus()));
    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(checkLanConnection()));
    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(checkNetworkClear()));
#ifdef __MIPS_LINUX__
    m_workTimer->start(5000);
    //更新一次,以后一直调用scan_r 5-6s
    system("wpa_cli -iwlan0 scan");
#endif
}

void HNEthManager::restoreWifi()
{
    QString name = m_curWifi[ESSID_NAME];
    QString password = m_curWifi[ESSID_PASS];
    QString encryt = m_curWifi[ESSID_ENCRYP];
    QString type = m_curWifi[ESSID_TYPE];

    char cmdbuf[MAX_PATH];
    char cmdresult[MAX_PATH];

    FILE* fp=fopen("/etc/wpa_supplicant.conf", "wb");
    fprintf(fp, "ctrl_interface=/var/run/wpa_supplicant\nctrl_interface_group=0\nap_scan=1\n\n");
    if("NO" == encryt)
    {
        pline() << "None Encryption";
        fprintf(fp, "network={\n\tssid=%s\n\tkey_mgmt=NONE\n\tpriority=5\n}\n", name.toAscii().data());
    }
    else if("WEP" == type)
    {
        pline() << "WEP Encryption";
        fprintf(fp, "network={\n\tssid=\"%s\"\n\tkey_mgmt=NONE\n\twep_key0=%s\n\twep_tx_keyidx=0\n\tpriority=5\n\tauth_alg=SHARED\n}\n",
                name.toAscii().data(), password.toAscii().data());
    }
    else if("WPA" == type)
    {
        pline() << "WPA Encryption";
        bzero(cmdbuf, MAX_PATH);
        bzero(cmdresult, MAX_PATH);
#if 0
        sprintf(cmdbuf, "wpa_passphrase %s %s | awk ‘NR==4{print $1}‘", name.toAscii().data(), wifiPassword.toAscii().data());
        FILE *pp = popen(cmdbuf, "r"); //建立管道
        fgets(cmdresult, sizeof(cmdresult), pp) ; //""
        pclose(pp);
        fprintf(fp, "network={\n\tssid=\"%s\"\n\tkey_mgmt=WPA-PSK\n\tgroup=TKIP\n\tpairwise=CCMP\n\tproto=WPA\n\t#psk=\"%s\"\n\t%s\tpriority=5\n}\n",
                name, wifiPassword, cmdresult);
#else
        sprintf(cmdbuf, "wpa_passphrase %s %s", name.toAscii().data(), password.toAscii().data());
        FILE *pp = popen(cmdbuf, "r"); //建立管道
        while(fgets(cmdresult, sizeof(cmdresult), pp))  //""
        {
            fputs(cmdresult, fp);
        }
        pclose(pp);
#endif
    }
    fclose(fp);
}

bool HNEthManager::restartWifi()
{
    char cmdbuf[MAX_PATH];
    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出
    bzero(cmdbuf, MAX_PATH);
    bzero(cmdresult, MAX_PATH);
    sprintf(cmdbuf, "wpa_cli -iwlan0 reconf");
    FILE *pp = popen(cmdbuf, "r"); //建立管道
    fgets(cmdresult, sizeof(cmdresult), pp); //""
    pclose(pp);

    if(strstr(cmdresult, "FAIL"))
        return false;
    return true;
}

void HNEthManager::saveScript()
{
    QString ip, mask, gw, dns;
    getAddr(ip, mask, gw, dns);

    QFile script("./net.sh");
    script.open(QFile::WriteOnly);
    char cmdbuf[MAX_PATH];
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "#!/bin/sh\n\n");
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "ifconfig eth0 %s netmask %s up\n",
            ip.toAscii().data(),
            mask.toAscii().data());
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "ifconfig wlan0 %s netmask %s up\n",
            ip.toAscii().data(),
            mask.toAscii().data());
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev eth0\n",
            gw.toAscii().data());
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev wlan0\n",
            gw.toAscii().data());
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "echo nameserver %s > /etc/resolv.conf\n", dns.toAscii().data());
    script.write(cmdbuf);

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "wpa_supplicant -B -Dwext -iwlan0 -c/etc/wpa_supplicant.conf\n");
    script.write(cmdbuf);
    script.close();

    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "chmod +x ./net.sh");
    system(cmdbuf);
}

void HNEthManager::config()
{
    char cmdbuf[MAX_PATH];
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "ip route | awk ‘{print $1}‘ | while read line; do ip route del $line; done");
    system(cmdbuf);
    //system("route");

    if(m_bUseDHCP)
    {
        m_thread->setnet(m_netName);
        m_thread->start();
        return;
    }

    QString ip, mask, gw, dns;
    getAddr(ip, mask, gw, dns);

    pline() << m_netName << ip << mask << gw << dns;

    // add .0 route
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "ifconfig %s 0.0.0.0 up", m_netName.toAscii().data());
    system(cmdbuf);
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "ifconfig %s %s netmask %s",
            m_netName.toAscii().data(),
            ip.toAscii().data(),
            mask.toAscii().data());
    system(cmdbuf);
    QStringList sl = gw.split(".");
    if(sl.size() < 3) { sl.clear(); sl << "0" << "0" << "0" << "0";}
    QString net = QString("%1.%2.%3.0").arg(sl[0]).arg(sl[1]).arg(sl[2]);
#if 0
    //dhcp后 ifconfig up 引发了添加这条route
    //ifconfig 0.0.0.0 也能引发添加这条route
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "route add -net %s netmask %s dev %s",
            net.toAscii().data(),
            mask.toAscii().data(),
            m_netName.toAscii().data());
    system(cmdbuf);
#endif
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev %s",
            gw.toAscii().data(),
            m_netName.toAscii().data());
    system(cmdbuf);
    //system("route");
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "echo nameserver %s > /etc/resolv.conf", dns.toAscii().data());
    system(cmdbuf);
}

void HNEthManager::saveAddr(QString ip, QString mask, QString gw, QString dns)
{
    QSettings netSet;
    netSet.setValue("/Network/IP", ip);
    netSet.setValue("/Network/Gateway", gw);
    netSet.setValue("/Network/Mask", mask);
    netSet.setValue("/Network/DNS", dns);
    netSet.sync();
}

void HNEthManager::getAddr(QString &ip, QString &mask, QString &gw, QString &dns)
{
    QSettings netSet;
    ip = netSet.value("/Network/IP").toString();
    mask = netSet.value("/Network/Mask").toString();
    gw = netSet.value("/Network/Gateway").toString();
    dns = netSet.value("/Network/DNS").toString();
}

void HNDhcpThread::run()
{
    char cmdbuf[MAX_PATH];
    bzero(cmdbuf, MAX_PATH);
    sprintf(cmdbuf, "udhcpc -i %s", net.toAscii().data());
    system(cmdbuf);
    emit passed(net);
}

void HNNetworkClearThread::run()
{
    static bool _bclear = false;
    bool bclear = false;
    char cmdbuf[MAX_PATH];
    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出
    bzero(cmdbuf, MAX_PATH);
    bzero(cmdresult, MAX_PATH);
    sprintf(cmdbuf, "ping 222.175.114.244 -w 2 -c 1");
    FILE *pp = popen(cmdbuf, "r"); //建立管道
    while(fgets(cmdresult, sizeof(cmdresult), pp))
    {
        if(strstr(cmdresult, "1 packets transmitted, 1 packets received, 0% packet loss"))
            bclear = true;
        break;
    }
    pclose(pp);

    if(_bclear != bclear)
    {
        if(bclear)
            emit cleared();
        else
            emit notcleared();
        _bclear = bclear;
    }

    return;
}
时间: 2024-10-25 14:13:08

Qt 嵌入式 利用wpa_supplicant编写WIFI、有线网络管理器的相关文章

转:Qt 嵌入式开发环境搭建

地址: http://www.cnblogs.com/lishixian/articles/3013897.html         作者:lsx_007 这里主要是记录了自己在搭建嵌入式开发环境时阅读的一些有价值的参考文档,文档主要来自于网络,由于是从文库中下载,所以也不知道 文档的出在哪?因为个人觉得总结的比较好,我暂且拿过来记录下,当然在此基础上也会加上我自己的理解!这篇文章主要是以问答的形式来组织. QT嵌入式开发环境是本文所要介绍的内容,我们先看看Qt的各个版本简介: 1.什么是QT

利用360免费wifi搭建局域网让他人访问Oracle数据库

步骤很简答有 第一部:安装完360免费,点击运行 第二部:关闭本地计算机的防火墙(找了半天问题所在后来才发现防火墙没关..关于防火墙的作用以后地看看 还有子网掩码) 第三部:就是让他人计算机通过PSQL连接你的数据库了(要是不想配置服务名的话把服务名改写为ip地址/数据库名) ip地址可以通过查看ipconfig得到 或者查看本地连接 利用360免费wifi搭建局域网让他人访问Oracle数据库,布布扣,bubuko.com

Qt Widget 利用 Qt4.5 实现酷炫透明窗体

本文讲述的是Qt Widget 利用 Qt4.5 实现酷炫透明窗体,QWidget类中的每一个窗口部件都是矩形,并且它们按Z轴顺序排列的.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. 先来看内容吧. Qt4.2引入了QWidget::setWindowOpacity函数, 可以为窗体设置透明度, 从0.0到1.0之间, 值越小越透明. 经过设置的窗体可以整体呈现透明的效果. 但这种设置比较粗糙, 只能设一个整体的效果,大概只有比如像拖动的时候能用一下,大多数时候都不太实用.在

利用多线程编写 生产者-消费者 关系

package ace; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; /** * 利用多线程编写 生产者-消费者 关系 */ public class ProductionAndConsumption { private static ArrayList<String> products = new ArrayList<String>(); // 产品 private

利用Cubieborad破解WiFi

http://blog.hibeiyu.com/archives/518 利用Cubieborad破解WiFi,布布扣,bubuko.com

使用Qt Creator 2.60编写C/C++程序

使用Qt Creator 2.60编写C/C++程序(Windows7-64bit和Ubuntu12.10-64bit). 一.Windows7-64bit +MinGW: 从官网下载qt creator安装,如果没有安装qt(注意qt和qt creator不是一回事)的话是没办法直接使用的,因为qt creator默认使用qmake来构建项目,而qmake是qt的一部分,由于qt太大了,不想安装,就使用cmake来进行构建,安装好之后配置一下: 依次选择:工具->选项->构建和运行->

看我如何利用Shell编写vsftpd管理软件

今天弄服务器的时候无意间用到此脚本,觉得当时写的虽然不咋样,但还是有点借鉴意义,就拿出来给大家看看.希望大家喜欢 先看看演示视频 看我如何利用Shell编写vsftpd管理软件 高清版下载: 百度云下载 OK然后我们来看看脚本的实现过程,时间有点久了当时的想法可能现在有点想不起来了,解释的不对的地方望见谅 脚本分为7个部分,这里我只做简单的解释 第一部分 脚本开始就利用awk提取日志中的用户名字段保存到tmp目录下的ftplog-userlist.txt文件中,方便后面查询 然后开始信息的展示,

如何利用CSS3编写一个满屏的布局

如何利用CSS3编写一个满屏的布局 css3的出现能帮助我们更加轻松的实现各种想要的效果,例如写一个刚好满屏的布局,我们就可以利用CSS3的弹性盒模型来实现. 先来贴出html布局代码: 1 <%- include header %> 2 <div class="wrapper"> 3 <div id="appswall"> 4 <div class="adsapp-title"><butto

利用MFC编写计算器

端午节这两天没什么事,就用MFC写了一个简单的计算器,界面做的也比较简单,如下图1,可以进行简单的加.减.乘和除功能,小数点显示这块做的不是很好,比如输入1.2,不会一个个的显示,而是先显示"1",后同时显示".2",还有就是遇到0.00时,显示的也不够人性化,哎,就这样吧... 图1 1.建立工程:New -> Projects,选择Win32 MFC AppWizard(exe),并输入工程(counter)名字及设置好路径,点击OK,选择"Di