gige工业相机突破(一,准备资源)

news2024/11/17 10:02:50

gige相机能不能绕开相机生产商提供的sdk,而直接取到像?

两种办法,第一,gige vision2.0说明书,第二,genicam

首先你会去干什么事?

好几年,我都没有突破,老虎吃天,不知道从哪里下抓。

神奇的事,2023年底,我遇到了genicam。

这给我打开了另一扇窗。

幸运的是,我找到了三个源程序,有一个是可以运行的在vs2022的c#下,使用wpf,说实在,我不懂wpf,c#我只会winform。

另外两个源程序,一个是c++语言版本的,他支持linux运行和windows运行,我以前搞过mfc vs c++,Linux不懂,注释掉,运行windows版本,编译不通过,一大堆问题,几度放弃。

csdn下,也有此作者的下载:

另外一个是c语言的,可是很多年前学过的c语言忘完了,以及socket通信,也忘完了。也支持linux运行和windows运行,注释掉Linux不懂,运行windows版本,编译能通过,花了好大功夫。

得到一个结论,gige相机和程序间是一问一答方式,这个很像多年前用vc++的api函数控制光驱的关闭,只需要发消息就行了,这是我对gige工业相机最大的认识,在这种信念下,就一步一步调试出来了。

这样很多知识就捡回来了,c呀,c++呀,还有socket通信呀。这个c语言版本主要提供了gige相机和程序间通信soket互问互答,虽然没结果,但这个认识很重要。

上面c++版本的程序,是可以见到相机图像的程序,调试成功完成后,最好用windows的socket,不要用gil以及其他第三方包,你理解了这个c语言版本,c++版本就能有很大的突破。

最好的wpf版本,c#写的,有时能运行,出图像,有时不能,我有点怀疑c#的机制,这些都是次要的,关键是,他能运行,你可以一步一步看下去,理解代码,c++版本的调试成功,这个c#可出图版本功劳巨大,虽然不懂wpf,上面走了很多冤枉路,但是wpf也懂了不少,没人教,也能学个半吊子。

还有一个很重要的工具,就是wireshark,他能监控出来,你的程序出现图像显示,执行了那些命令,我有监控海康自带的gige工业相机的连接,打开和显示。

并和我调试的程序对比,突破重重障碍。

后来又写了一版gige工业相机取像,起名“一步登天”,因为我只用收发命令就能得到gige工业相机的图像,其他研究过的,大部用不着了,而你就会发现gige vision2.0使用说明书和genicam只是协议而已。

我的c语言版本,c#版本不存在相机取像问题,没有wpf有时打不开的情况。

我专门买了海康的500万gige工业相机来做这件事,结果是令人满意的。

但是,换作basler gige200万工业相机,不行,换作海康2000万彩色gige工业相机也打不开图像,也就是说其他品牌相机也不行,你应该知道秘密在哪里,在wireshark里,监控对比后,修改程序中的互动命令,一定可以。

看来,还是没有一步登天,但这是一件有意义的事情。

c语言源代码如下:

// Changshigegesecond.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
//#ifdef _WINDOWS_

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
//Windows.h 标头默认包含 Windows Sockets 1.1 的 Winsock.h 头文件
//Winsock.h 头文件中的声明将与 Windows Sockets 2.0 所需的 Winsock2.h 头文件中的声明冲突
//WIN32_LEAN_AND_MEAN宏可防止 Windows.h 标头包含 Winsock.h

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

//#include <ws2tcpip.h>
#include <mswsock.h>
#include <malloc.h>
//#include "winsock2.h"
//#include <windows.h>

#ifndef ETH_ALEN
#define ETH_ALEN       6              // 以太网地址大小
#define ETH_HLEN       14             // 以太网头部大小
#define ETH_DATA_LEN   1500           // 最大帧负载数据大小
#define ETH_FRAME_LEN  1514           // 最大帧大小,头部+负载数据
#endif
//#else
//#include <unistd.h>
//#include <sys/types.h>          /* See NOTES */
//#include <sys/socket.h>
//#include <sys/ioctl.h>
//#include <net/if.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <netinet/if_ether.h>
//#include <netinet/in.h>
//#include <linux/sockios.h>
//#include <net/route.h>
//#endif
#include <errno.h>

//#include <iostream>

#include <iphlpapi.h>
#include <sstream>
#include <iomanip>

//using namespace std;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
//#ifdef _WINDOWS_//这个和linux相关,回头研究一下20240310
//#endif

//使用 Winsock 的应用程序必须与 Ws2_32.lib 库文件链接
#pragma comment(lib, "Ws2_32.lib")

#if 1//most hardware
#define MY_DEV_NAME "eth0"
#else
#define MY_DEV_NAME "ens33"
#endif
//char m_szLocalIp[32]="192.168.1.230";//本地千兆网卡的ip?
//char m_szLocalMask[32]="255.255.255.0";
//char m_szLocalGateway[32]="192.168.1.254";
char m_szLocalIp[32]="192.168.20.48";//本地千兆网卡的ip?
char m_szLocalMask[32]="255.255.255.0";
char m_szLocalGateway[32]="192.168.20.254";

char m_szLocalMac[32];
uint8 m_LocalMacAddr[ETH_ALEN];

int SetIfAddr(char *ifname, char *Ipaddr, char *mask, char *gateway);
int GetIfAddr(char *ifname, char *Ipaddr, char *mask, char *gateway);
int addRoute(char *ipAddr, char *mask,char *gateWay,char* devName);

char m_szRemoteIp[32];//接收到远端千兆网卡的ip?
char m_szRemoteMask[32];
char m_szRemoteGateway[32];
char m_szRemoteMac[32];

uint32 m_dwRemotePort;

struct gvcp_cmd_header{
    uint8 cMsgKeyCode;//0x42
    uint8 cFlag;//0x11 allow broadcast ack;ack required
    uint16 wCmd;//discovery_cmd=2;FORCEIP_CMD = 4;READREG_CMD=0x80
    uint16 wLen;//payload length
    uint16 wReqID;// request id = 1;READREG id=12345
};

struct gvcp_forceip_payload{
    uint8 Mac[8];//last 6 byte
    uint8 CurIP[16];//last 4 byte
    uint8 SubMask[16];//last 4 byte
    uint8 Gateway[16];//last 4 byte
};

struct gvcp_ack_header{
    uint16 wStatus;//success=0;
    uint16 wAck;//discover_ack=3;forceip_ack=5;READREG_ACK=0x81
    uint16 wLen;
    uint16 wReqID;
};

struct gvcp_ack_payload{
    uint32 dwSpecVer;
    uint32 dwDevMode;
    uint8 Mac[8];//last 6 byte
    uint32 dwSupIpSet;
    uint32 dwCurIpSet;
    //uint8 unused1[12];
    uint8 CurIP[16];//last 4 byte
    uint8 SubMask[16];//last 4 byte
    uint8 Gateway[16];//last 4 byte
    char szFacName[32];//first
    char szModelName[32];//first
    char szDevVer[32];
    char szFacInfo[48];
    char szSerial[16];
    char szUserName[16];
};

struct gvcp_discover_cmd{
    struct gvcp_cmd_header header;
};
struct gvcp_discover_ack{
    struct gvcp_ack_header header;
    struct gvcp_ack_payload payload;
};
struct gvcp_forceip_cmd{
    struct gvcp_cmd_header header;
    struct gvcp_forceip_payload payload;
};
struct gvcp_forceip_ack{
    struct gvcp_ack_header header;
};
struct gvcp_readreg_cmd{
    struct gvcp_cmd_header header;
    uint32 dwRegAddr;
};
struct gvcp_readreg_ack{
    struct gvcp_ack_header header;
    uint32 dwRegValue;
};
struct gvcp_writereg_cmd {
    struct gvcp_cmd_header header;
    uint32 dwRegAddr;
    uint32 dwRegValue;
};

struct gvcp_writereg_ack {
    struct gvcp_ack_header header;
};

struct gvcp_readmem_cmd {
    struct gvcp_cmd_header header;
    uint32 dwMemAddr;
    uint32 dwMemCount;//last 2 byte
};
struct gvcp_readmem_ack {
    struct gvcp_ack_header header;
    uint32 dwMemAddr;
    char* pMemBuf;
};
#define GVCP_DISCOVERY_CMD    2
#define GVCP_DISCOVERY_ACK    3
#define GVCP_FORCEIP_CMD    4
#define GVCP_FORCEIP_ACK    5
#define GVCP_READREG_CMD    0x80
#define GVCP_READREG_ACK    0x81
#define GVCP_WRITEREG_CMD    0x82
#define GVCP_WRITEREG_ACK    0x83
#define GVCP_READMEM_CMD    0x84
#define GVCP_READMEM_ACK    0x85

//#ifndef ETH_ALEN
//#define ETH_ALEN       6              // 以太网地址大小
//#define ETH_HLEN       14             // 以太网头部大小
//#define ETH_DATA_LEN   1500           // 最大帧负载数据大小
//#define ETH_FRAME_LEN  1514           // 最大帧大小,头部+负载数据
//#endif

int getLoaclMac(char *szMac) //获取本地的mac
{
#ifndef _WINDOWS_
    char *device=MY_DEV_NAME; //eth0是网卡设备名
    //unsigned char macaddr[ETH_ALEN]; //ETH_ALEN(6)是MAC地址长度
    struct ifreq req;
    int err,i;
    int s;
 
 
    s=socket(AF_INET,SOCK_DGRAM,0); //internet协议族的数据报类型套接口
    strcpy(req.ifr_name,device); //将设备名作为输入参数传入
    err=ioctl(s,SIOCGIFHWADDR,&req); //执行取MAC地址操作
    close(s);
    if(err != -1) { 
        memcpy(m_LocalMacAddr,req.ifr_hwaddr.sa_data,ETH_ALEN); //取输出的MAC地址
        for(i = 0; i < ETH_ALEN; i++) {
            sprintf(szMac, "%s%02x",szMac, m_LocalMacAddr[i]&0xff);
            if(i != ETH_ALEN - 1) {
                sprintf(szMac, "%s:", szMac);
            }
        }
 
    } else {
        return -1;
    }
#else
    bool ret = false;

    ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
    PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
    if (pAddresses == NULL)
        return false;
    // Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
    if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
    {
        free(pAddresses);
        pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
        if (pAddresses == NULL)
            return false;
    }


    if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
    {
        // If successful, output some information from the data we received
        for (PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
        {
            // 确保MAC地址的长度为 00-00-00-00-00-00
            if (pCurrAddresses->PhysicalAddressLength != 6)
                continue;
            //char acMAC[32];
            memcpy(m_LocalMacAddr, pCurrAddresses->PhysicalAddress, ETH_ALEN); //取输出的MAC地址
            sprintf(szMac, "%02X:%02X:%02X:%02X:%02X:%02X",
                int(pCurrAddresses->PhysicalAddress[0]),
                int(pCurrAddresses->PhysicalAddress[1]),
                int(pCurrAddresses->PhysicalAddress[2]),
                int(pCurrAddresses->PhysicalAddress[3]),
                int(pCurrAddresses->PhysicalAddress[4]),
                int(pCurrAddresses->PhysicalAddress[5]));
            //macOUT = acMAC;
            ret = true;
            break;
        }
    }
    free(pAddresses);
#endif
    return 0;
}
int gvcp_ack_discover(int iFd,char* szIp,char* szMask,char* szGateway, uint16 wReqID,uint32 dwPort,uint8* pMac)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;
    int iOptval = 1;
    struct sockaddr_in Addr;
    int bNeedClose=0;
    if(iFd<0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose=1;
    }
       if (setsockopt(iFd, SOL_SOCKET,  SO_REUSEADDR, (char*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
 /*   if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, (char*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }*/
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("192.168.20.54");
    Addr.sin_port = htons(dwPort);

    /*memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(3956);*/
    //static struct gvcp_discover_cmd cmd_msg;
    //memset(&cmd_msg, 0, sizeof(struct gvcp_discover_ack));

    static  struct gvcp_discover_ack ack_msg;
    memset(&ack_msg, 0, sizeof(struct gvcp_discover_ack));
    ack_msg.header.wStatus=htons(0);
    ack_msg.header.wAck=htons(GVCP_DISCOVERY_ACK);
    ack_msg.header.wLen=htons(sizeof(struct gvcp_ack_payload));
    ack_msg.header.wReqID=htons(1);
    ack_msg.payload.dwSpecVer=htonl(0x010002);;
    ack_msg.payload.dwDevMode=htonl(1);
    //uint8 MyMac[6]={0xc4,0x2f,0x90,0xf1,0x71,0x3e};
    memcpy(&ack_msg.payload.Mac[2],m_LocalMacAddr,6);
    ack_msg.payload.dwSupIpSet=htonl(0x80000007);
    ack_msg.payload.dwCurIpSet=htonl(0x00005);
    //uint8 unused1[12];
    *((uint32*)&ack_msg.payload.CurIP[12])=inet_addr(m_szLocalIp);//last 4 byte
    *((uint32*)&ack_msg.payload.SubMask[12])=inet_addr(m_szLocalMask);//last 4 byte
    *((uint32*)&ack_msg.payload.Gateway[12])=inet_addr(m_szLocalGateway);//last 4 byte
    //strcpy(ack_msg.payload.szFacName,"GEV");//first
    //strcpy(ack_msg.payload.szModelName,"MV-AA003-50GM");//first
    //strcpy(ack_msg.payload.szDevVer,"V2.8.6 180210 143913");
    //strcpy(ack_msg.payload.szFacInfo,"GEV");
    //strcpy(ack_msg.payload.szSerial,"00C31976084");
    //strcpy(ack_msg.payload.szUserName,"");
    strcpy(ack_msg.payload.szFacName,"GEV");//first
    strcpy(ack_msg.payload.szModelName,"MV-CE050-30GM");//first
    strcpy(ack_msg.payload.szDevVer,"V2.10.0 191122 355697");
    strcpy(ack_msg.payload.szFacInfo,"GEV");
    strcpy(ack_msg.payload.szSerial,"00E36658695");
    strcpy(ack_msg.payload.szUserName,"");
    char* rgMessage=(char*)&ack_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_discover_ack);

    //char* rgMessage = (char*)&cmd_msg;
    //uint32 dwMsgLen = sizeof(struct gvcp_discover_cmd);

    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno,strerror(errno));
            return -1;
        }
        printf("gvcp_ack_discover=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if(bNeedClose>0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
int gvcp_ask_forceip(int iFd, uint16 wReqID, uint32 dwPort)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;

    struct sockaddr_in Addr;
    int bNeedClose = 0;
    if (iFd < 0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose = 1;
    }
    int iOptval = 1;
#ifdef _WINDOWS_
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt SO_REUSEADDR failed!");
    }
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
#else
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
#endif
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(dwPort);

    static struct gvcp_forceip_ack my_msg;
    memset(&my_msg, 0, sizeof(struct gvcp_forceip_ack));
    my_msg.header.wStatus = htons(0);
    my_msg.header.wAck = htons(GVCP_FORCEIP_ACK);
    my_msg.header.wLen = htons(0);
    my_msg.header.wReqID = htons(wReqID );

    char* rgMessage = (char*)&my_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_forceip_ack);
    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno, strerror(errno));
            return -1;
        }
        printf("gvcp_ask_forceip=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if (bNeedClose > 0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
int gvcp_ask_readreg(int iFd, uint16 wReqID,uint32 dwPort, uint32 dwRegAddr, uint32 dwRegValue)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;

    struct sockaddr_in Addr;
    int bNeedClose = 0;
    if (iFd < 0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose = 1;
    }
    int iOptval = 1;
#ifdef _WINDOWS_
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt SO_REUSEADDR failed!");
    }
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
#else
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
#endif
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(dwPort);

    static struct gvcp_readreg_ack my_msg;
    memset(&my_msg, 0, sizeof(struct gvcp_readreg_ack));
    my_msg.header.wStatus = htons(0);
    my_msg.header.wAck = htons(GVCP_READREG_ACK);
    my_msg.header.wLen = htons(4);
    my_msg.header.wReqID = htons(wReqID);
    my_msg.dwRegValue = htonl(dwRegValue);;

    char* rgMessage = (char*)&my_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_readreg_ack);
    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno, strerror(errno));
            return -1;
        }
        printf("gvcp_ask_readreg=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if (bNeedClose > 0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
int gvcp_ask_writereg(int iFd, uint16 wReqID, uint32 dwPort)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;

    struct sockaddr_in Addr;
    int bNeedClose = 0;
    if (iFd < 0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose = 1;
    }
    int iOptval = 1;
#ifdef _WINDOWS_
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt SO_REUSEADDR failed!");
    }
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
#else
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
#endif
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(dwPort);

    static struct gvcp_writereg_ack my_msg;
    memset(&my_msg, 0, sizeof(struct gvcp_writereg_ack));
    my_msg.header.wStatus = htons(0);
    my_msg.header.wAck = htons(GVCP_WRITEREG_ACK);
    my_msg.header.wLen = htons(0);
    my_msg.header.wReqID = htons(wReqID);

    char* rgMessage = (char*)&my_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_writereg_ack);
    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno, strerror(errno));
            return -1;
        }
        printf("gvcp_ask_writereg=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if (bNeedClose > 0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
int gvcp_cmd_discover(int iFd)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;
    
    struct sockaddr_in Addr;
    int bNeedClose = 0;
    if (iFd < 0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose = 1;
    }
    int iOptval = 1;
#ifdef _WINDOWS_
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt SO_REUSEADDR failed!");
    }
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
#else
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
#endif
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(3956);

    static struct gvcp_discover_cmd cmd_msg;
    memset(&cmd_msg, 0, sizeof(struct gvcp_discover_ack));
    cmd_msg.header.cMsgKeyCode = 0x42;
    cmd_msg.header.cFlag=0x11;//0x11 allow broadcast ack;ack required
    cmd_msg.header.wCmd= htons(GVCP_DISCOVERY_CMD);//discovery_cmd=2;FORCEIP_CMD = 4;READREG_CMD=0x80
    cmd_msg.header.wLen = htons(0);//payload length
    cmd_msg.header.wReqID = htons(1);// request id = 1;READREG id=12345


    char* rgMessage = (char*)&cmd_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_discover_cmd);
    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno, strerror(errno));
            return -1;
        }
        printf("gvcp_cmd_discover=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if (bNeedClose > 0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
int gvcp_cmd_discover(int iFd,bool isreadreg)
{
    //char rgMessage[128] = "I am sending message to you!";
    //int iFd;
    int iSendbytes;
    
    struct sockaddr_in Addr;
    int bNeedClose = 0;
    if (iFd < 0)
    {
        if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
            printf("socket fail\n");
            return -1;
        }
        bNeedClose = 1;
    }
    int iOptval = 1;
#ifdef _WINDOWS_
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt SO_REUSEADDR failed!");
    }
    BOOL    bBroadcast = true;
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) < 0)
    {
        printf("setsockopt SO_BROADCAST failed!");
    }
#else
    if (setsockopt(iFd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!");
    }
#endif
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = inet_addr("255.255.255.255");
    Addr.sin_port = htons(3956);

    static struct gvcp_discover_cmd cmd_msg;
    memset(&cmd_msg, 0, sizeof(struct gvcp_discover_ack));
    cmd_msg.header.cMsgKeyCode = 0x42;
    cmd_msg.header.cFlag=0x11;//0x11 allow broadcast ack;ack required
    //cmd_msg.header.wCmd= htons(GVCP_DISCOVERY_CMD);//discovery_cmd=2;FORCEIP_CMD = 4;READREG_CMD=0x80
    //cmd_msg.header.wLen = htons(0);//payload length
    //cmd_msg.header.wReqID = htons(1);// request id = 1;READREG id=12345
    cmd_msg.header.wCmd= htons(0x80);//discovery_cmd=2;FORCEIP_CMD = 4;READREG_CMD=0x80
    cmd_msg.header.wLen = htons(0);//payload length
    cmd_msg.header.wReqID = htons(1);// request id = 1;READREG id=12345

    char* rgMessage = (char*)&cmd_msg;
    uint32 dwMsgLen = sizeof(struct gvcp_discover_cmd);
    //while (1)
    {
        if ((iSendbytes = sendto(iFd, rgMessage, dwMsgLen, 0, (struct sockaddr*)&Addr, sizeof(struct sockaddr))) == -1)
        {
            printf("sendto fail, errno=%d,%s\n", errno, strerror(errno));
            return -1;
        }
        printf("gvcp_cmd_discover=%s, rgMessageLen=%d,iSendbytes=%d\n", rgMessage, dwMsgLen, iSendbytes);
        //sleep(1);
    }
    if (bNeedClose > 0)
    {
#ifdef _WINDOWS_
        closesocket(iFd);
#else
        close(iFd);
#endif
    }

    return 0;
}
//#ifdef _WINDOWS_
//extern void InitConsoleWindow();
//int GvcpServer(void) 
//#else

int _tmain(int argc, _TCHAR* argv[])
//#endif
{
     WSADATA wsaData;
     WSAStartup(MAKEWORD(2, 0), &wsaData);
     printf("wVersion: %d.%d\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
printf("wHighVersion: %d.%d\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
printf("szDescription: %s\n", wsaData.szDescription);
printf("szSystemStatus: %s\n", wsaData.szSystemStatus);
    // ...
    if(1)
    {
    //Linux下C语言获取网卡信息(IPv4)
     int iRtn = GetIfAddr(MY_DEV_NAME, m_szLocalIp, m_szLocalMask, m_szLocalGateway);
    if(iRtn<0)    //Linux下C语言重置网卡信息(IPv4)
    {
        printf("GetIfAddr Error(%d) -> ResetIfAddr\n",iRtn);
        iRtn = SetIfAddr(MY_DEV_NAME, m_szLocalIp, m_szLocalMask, m_szLocalGateway);
        if(iRtn<0)
        {
            printf("SetIfAddr Error(%d)\n", iRtn);
        }
           
    }
    //在网络通信中,路由是指传输数据包的路径。当一个数据包需要从一个网络发送到另一个网络时,
    //    它需要经过一系列的路由器,这些路由器会根据预设的路由表来决定应该将数据包发送到哪个方向的网络。
    //    静态路由是手动配置的路由,它不会随着网络拓扑的变化而自动更新。在某些情况下,
    //    需要手动添加静态路由来实现网络通信,这时就需要使用route add命令
    iRtn = addRoute("255.255.255.0", "255.255.255.0", m_szLocalGateway, MY_DEV_NAME);
    if(iRtn<0)
    {
        printf("addRoute Error(%d)\n", iRtn);
    }
    int iAddrLength;
    char rgMessage[2014];
    int iOptval = 1;
    int iFd;
    struct sockaddr_in Addr;
 //下面与tcpip正常步骤相似,udp
    if ((iFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        printf("socket fail\n");
        return -1;
    }
    else
    {
        printf("socket ok\n");
    }
    if (setsockopt(iFd, SOL_SOCKET, SO_REUSEADDR, (char*)&iOptval, sizeof(int)) < 0)
    {
        printf("setsockopt failed!\n");
    }
    else
    {
        printf("setsockopt ok\n");
    }
    memset(&Addr, 0, sizeof(struct sockaddr_in));
    Addr.sin_family = AF_INET;
    Addr.sin_addr.s_addr = INADDR_ANY;
    Addr.sin_port = htons(3956);//这里使用的端口号也是3956
    iAddrLength = sizeof(Addr);

    if (bind(iFd, (struct sockaddr *)&Addr, sizeof(Addr)) == -1)//绑定
    {
        printf("bind failed!\n");
    }
    else
    {
        printf("bind ok\n");
    }
    
    int iTryCount = 10;
    bool DISCOVERYed=false;
    while (1)
    {
        if(!DISCOVERYed)
        {
        gvcp_cmd_discover(iFd);//要先发一个探索包吗?如果发,应该携带本地的port和ip
        Sleep(200);
        }else
        {
        gvcp_cmd_discover(iFd,true);
            Sleep(200);
        }

        int iRecvLen=0;
        if ((iRecvLen=recvfrom(iFd, rgMessage, sizeof(rgMessage), 0, (struct sockaddr *)&Addr, &iAddrLength)) == -1)
        {
            printf("recv failed!\n");
        }//本地接受到远端的消息
        printf("recv len =%d\n", iRecvLen);
        unsigned short* pBuf = (unsigned short*)rgMessage;
        strncpy(m_szRemoteIp, inet_ntoa(Addr.sin_addr), 16);
        if('5'==m_szRemoteIp[11]&&'4'==m_szRemoteIp[12]) DISCOVERYed=true;
        strncpy(m_szRemoteMask, "255.255.255.0", 16);
        strncpy(m_szRemoteGateway, inet_ntoa(Addr.sin_addr), 16);
        m_dwRemotePort = ntohs(Addr.sin_port);
        getLoaclMac(m_szLocalMac);//本地的ip,port和mac不同吗?
        if (iRecvLen >= 8)
        {
            printf("recv from %s:%d-%04x-%04x-%04x-%04x\n",
                inet_ntoa(Addr.sin_addr), ntohs(Addr.sin_port),
                ntohs(pBuf[0]), ntohs(pBuf[1]), ntohs(pBuf[2]), ntohs(pBuf[3]));

            struct gvcp_cmd_header* pHeader = (struct gvcp_cmd_header*)rgMessage;
            static struct gvcp_cmd_header m_CmdHeader;
            m_CmdHeader.cMsgKeyCode = pHeader->cMsgKeyCode;// 0x42;允许广播 ack
            m_CmdHeader.cFlag = pHeader->cFlag;//0x11 allow broadcast ack;ack required
            m_CmdHeader.wCmd = ntohs(pHeader->wCmd);//discovery_cmd=2;FORCEIP_CMD = 4;READREG_CMD=0x80
            m_CmdHeader.wLen = ntohs(pHeader->wLen);//payload length
            m_CmdHeader.wReqID = ntohs(pHeader->wReqID);// request id = 1;READREG id=12345
            if (m_CmdHeader.cMsgKeyCode == 0x42 && m_CmdHeader.wCmd == GVCP_DISCOVERY_CMD)
            {
                //要先发一个探索包吗?如果发,应该携带本地的port和ip
                //这里是gvcp发现回应,还要携带本地的mac地址m_LocalMacAddr
                gvcp_ack_discover(iFd, m_szLocalIp, m_szLocalMask, m_szLocalGateway, m_CmdHeader.wReqID, m_dwRemotePort, m_LocalMacAddr);
            }
            else if (m_CmdHeader.cMsgKeyCode == 0x42 && m_CmdHeader.wCmd == GVCP_FORCEIP_CMD&&iRecvLen>=sizeof(struct gvcp_forceip_cmd))
            {//如果是收到强力ip命令,force有力量的意思,f=ma
                struct sockaddr_in GetAddr;
                memset(&GetAddr, 0, sizeof(struct sockaddr_in));
                GetAddr.sin_family = AF_INET;
                GetAddr.sin_addr.s_addr = INADDR_ANY;
                GetAddr.sin_port = htons(3956);

                struct gvcp_forceip_cmd* pMyCmd = (struct gvcp_forceip_cmd*)rgMessage;

                uint8 GetMac[6];// = { 0xc4,0x2f,0x90,0xf1,0x71,0x3e };
                memcpy(GetMac, &(pMyCmd->payload.Mac[2]), 6);
                printf("maccmp %s:%02x:%02x:%02x:%02x:%02x:%02x\n",m_szLocalMac,
                GetMac[0],GetMac[1],GetMac[2],GetMac[3],GetMac[4],GetMac[5]);
                if (memcmp(m_LocalMacAddr, GetMac, 6) == 0)//匹配成功
                {
                    
                    GetAddr.sin_addr.s_addr = *((uint32*)&pMyCmd->payload.CurIP[12]);// = inet_addr("192.168.101.57");//last 4 byte
                    strncpy(m_szLocalIp, inet_ntoa(GetAddr.sin_addr), 16);
                    GetAddr.sin_addr.s_addr = *((uint32*)&pMyCmd->payload.SubMask[12]);// = inet_addr("255.255.255.0");//last 4 byte
                    strncpy(m_szLocalMask, "255.255.255.0", 16);
                    GetAddr.sin_addr.s_addr = *((uint32*)&pMyCmd->payload.Gateway[12]);// = inet_addr("192.168.101.254");//last 4 byte
                    strncpy(m_szLocalGateway, inet_ntoa(GetAddr.sin_addr), 16);
                    if(SetIfAddr(MY_DEV_NAME, m_szLocalIp, m_szLocalMask, m_szLocalGateway)<0)
                        printf("SetIfAddr Failed"); 
                    //reget if addr
                    GetIfAddr(MY_DEV_NAME, m_szLocalIp, m_szLocalMask, m_szLocalGateway);
                    //struct gvcp_forceip_payload
                    gvcp_ask_forceip(iFd, m_CmdHeader.wReqID, m_dwRemotePort);
                }

            }
            else if (m_CmdHeader.cMsgKeyCode == 0x42 && m_CmdHeader.wCmd == GVCP_READREG_CMD&&iRecvLen >= sizeof(struct gvcp_readreg_cmd))
            {//如果接受是读寄存器的命令
                struct gvcp_readreg_cmd* pMyCmd = (struct gvcp_readreg_cmd*)rgMessage;

                uint32 dwRegAddr = ntohl(pMyCmd->dwRegAddr);
                uint32 dwRegValue = 0;
                if (dwRegAddr == 0x0014)//Current IP Configuration
                {
                    //DHCP bit1
                    //LLA bit2
                    dwRegValue = 0x04;
                }
                else if (dwRegAddr == 0x00934)//(Gvcp Capability)
                {
                    dwRegValue = 0xf8400007;//
                }
                else if (dwRegAddr == 0x00938)//heartbeat timeout
                {
                    dwRegValue = 3000;//ms
                }
                else if (dwRegAddr == 0x00a00)//CCP (Control Channel Privilege)
                {
                    dwRegValue = 0;
                }
                printf("readreg:%08x=%08x\n",dwRegAddr,dwRegValue); 
                //向相机发出读寄存器询问
                gvcp_ask_readreg(iFd, m_CmdHeader.wReqID, m_dwRemotePort, dwRegAddr, dwRegValue);
            }
            else if (m_CmdHeader.cMsgKeyCode == 0x42 && m_CmdHeader.wCmd == GVCP_WRITEREG_CMD&&iRecvLen >= sizeof(struct gvcp_writereg_cmd))
            {//如果是写gvcp寄存器命令GVCP_WRITEREG_CMD
                struct gvcp_writereg_cmd* pMyCmd = (struct gvcp_writereg_cmd*)rgMessage;

                uint32 dwRegAddr = ntohl(pMyCmd->dwRegAddr);
                uint32 dwRegValue = ntohl(pMyCmd->dwRegValue);
                //下面是解读收到消息的结果
                if (dwRegAddr == 0x0014)//Current IP Configuration
                {
                    //DHCP bit1
                    //LLA bit2
                    //dwRegValue = 0x04;
                    if(dwRegValue&0x02)
                        printf("Set DHCP Enable\n"); 
                    if(dwRegValue&0x04)
                        printf("Set LLA Enable\n"); 
                }
                else if (dwRegAddr == 0x00934)//(Gvcp Capability)
                {
                    //dwRegValue = 0xf8400007;//
                    printf("Set Gvcp Capability:%08x\n",dwRegValue); 
                }
                else if (dwRegAddr == 0x00938)//heartbeat timeout
                {
                    //dwRegValue = 3000;//ms
                    printf("Set heartbeat timeout:%d\n",dwRegValue); 
                }
                else if (dwRegAddr == 0x00a00)//CCP (Control Channel Privilege)
                {
                    //dwRegValue = 0;
                    printf("Set CCP:%08x\n",dwRegValue); 
                }
                gvcp_ask_writereg(iFd, m_CmdHeader.wReqID, m_dwRemotePort);
            }
        }
    }

#ifdef _WINDOWS_
    closesocket(iFd);
#else
    close(iFd);
#endif

      }
    // ...
    WSACleanup();
    return 0;
}

int SetIfAddr(char *ifname, char *Ipaddr, char *mask, char *gateway)
{
    int fd=0;
    int rc=0;
#ifdef _WINDOWS_

#else
    struct ifreq ifr;
    struct sockaddr_in *sin;
    struct rtentry  rt;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        perror("socket   error");
        close(fd);
        return -1;
    }
    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);
    sin = (struct sockaddr_in*)&ifr.ifr_addr;
    sin->sin_family = AF_INET;

    //ipaddr
    if (inet_aton(Ipaddr, &(sin->sin_addr)) < 0)
    {
        perror("inet_aton ipaddr error");
        close(fd);
        return -2;
    }
    uint32 dwLocalIp = sin->sin_addr.s_addr;
    if (ioctl(fd, SIOCSIFADDR, &ifr) < 0)
    {
        perror("ioctl   SIOCSIFADDR   error");
        close(fd);
        return -3;
    }

    //netmask
    if (inet_aton(mask, &(sin->sin_addr)) < 0)
    {
        perror("inet_pton netmask error");
        close(fd);
        return -4;
    }
    if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0)
    {
        perror("ioctl");
        close(fd);
        return -5;
    }
    //boardcast
    sin->sin_addr.s_addr = (dwLocalIp&0x00FFFFFF)|0xFF000000;
    //if (inet_aton(gateway, &(sin->sin_addr)) < 0)
    //{
    //    perror("inet_pton boardcast error");
    //    close(fd);
    //    return -8;
    //}
    if (ioctl(fd, SIOCSIFBRDADDR, &ifr) < 0)
    {
        perror("ioctl");
        close(fd);
        return -9;
    }
    //gateway
    memset(&rt, 0, sizeof(struct rtentry));
    memset(sin, 0, sizeof(struct sockaddr_in));
    sin->sin_family = AF_INET;
    sin->sin_port = 0;
    if (inet_aton(gateway, &sin->sin_addr) < 0)
    {
        printf("inet_aton gateway error\n");
        return -6;
    }
    memcpy(&rt.rt_gateway, sin, sizeof(struct sockaddr_in));
    ((struct sockaddr_in *)&rt.rt_dst)->sin_family = AF_INET;
    ((struct sockaddr_in *)&rt.rt_genmask)->sin_family = AF_INET;
    rt.rt_flags = RTF_GATEWAY;
    if (ioctl(fd, SIOCADDRT, &rt) < 0)
    {
        perror("ioctl(SIOCADDRT) error in set_default_route\n");
        close(fd);
        return -7;
    }
    close(fd);
#endif
    return 0;

}
int GetIfAddr(char *ifname, char *Ipaddr, char *mask, char *gateway)
{

    int fd;
    int rc;
    int ret;
    int i=0;
#ifndef _WINDOWS_
    struct ifreq ifr;
    struct sockaddr_in sin;
    struct sockaddr_in* p_sin=0;
    struct rtentry  rt;

    fd = socket(AF_INET, SOCK_DGRAM, 0);//internet协议族的数据报类型套接口
    if (fd < 0)
    {
        perror("socket   error");
        return -1;
    }
    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);//将设备名作为输入参数传入
    p_sin = (struct sockaddr_in*)&ifr.ifr_addr;
    p_sin->sin_family = AF_INET;

    ret = ioctl(fd, SIOCGIFHWADDR, &ifr); //执行取MAC地址操作                                    
    if (ret < 0)
    {
        close(fd);
        perror("ioctl   SIOCGIFHWADDR   error");
        return -2;
    }
    
    {
        memcpy(m_LocalMacAddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); //取输出的MAC地址
        for (i = 0; i < ETH_ALEN; i++) {
            sprintf(m_szLocalMac, "%s%02x", m_szLocalMac, m_LocalMacAddr[i] & 0xff);
            if (i != ETH_ALEN - 1) {
                sprintf(m_szLocalMac, "%s:", m_szLocalMac);
            }
        }
        printf("MacAddr is :%s\n", m_szLocalMac);
    }

    //get the broadcast addr
    /* 获取当前网卡的广播地址 */
    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
    {
        close(fd);
        return -3;
    }
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    m_dwBroadcast = sin.sin_addr.s_addr;
    printf("broadcast is :%s\n", inet_ntoa(sin.sin_addr));

    //get the ip addr
    /* 获取当前网卡的IP地址 */
    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0)
    {
        close(fd);
        return -4;
    }
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    uint32 dwLocalIp = sin.sin_addr.s_addr;
    sprintf(m_szLocalIp,"%s", inet_ntoa(sin.sin_addr));
    printf("LocalIp is :%s(%x)\n", inet_ntoa(sin.sin_addr),dwLocalIp);

    /* 获取当前网卡的子网掩码 */
    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
    {
        close(fd);
        return -5;
    }
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    sprintf(m_szLocalMask, "%s", inet_ntoa(sin.sin_addr));
    printf("LocalMask is :%s\n", inet_ntoa(sin.sin_addr));

    /* 获取当前网卡的gateway */
    //if (ioctl(fd, SIOCGADDRT, &ifr) < 0)
    //{
    //    close(fd);
    //    return -5;
    //}
    //memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    sin.sin_addr.s_addr = (dwLocalIp&0x00FFFFFF)|0xFE000000;
    sprintf(m_szLocalGateway, "%s", inet_ntoa(sin.sin_addr));
    printf("LocalGateway is :%s\n", inet_ntoa(sin.sin_addr));

    close(fd);
#else

#endif
    return 0;
}


int addRoute(char *ipAddr, char *mask,char *gateWay,char* devName)
{
  int fd;
  int rc = 0;
#ifndef _WINDOWS_
  struct sockaddr_in _sin;
  struct sockaddr_in *sin = &_sin;
  struct rtentry  rt;
 
  do
  {
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0)
    {
      printf("addRoute: socket   error\n");
      rc = -1;
      break;
    }
    //网关  
    memset(&rt, 0, sizeof(struct rtentry));
    memset(sin, 0, sizeof(struct sockaddr_in));
    sin->sin_family = AF_INET;
    sin->sin_port = 0;
    if(inet_aton(gateWay, &sin->sin_addr)<0)
    {
      printf( "addRoute:  gateWay inet_aton error\n" );
      rc = -2;
      break;
    }
    memcpy ( &rt.rt_gateway, sin, sizeof(struct sockaddr_in));
    ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
    if(inet_aton(ipAddr, &((struct sockaddr_in *)&rt.rt_dst)->sin_addr)<0)
    {
      printf( "addRoute:  dst inet_aton error\n" );
      rc = -3;
      break;
    }
    ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
    if(inet_aton(mask, &((struct sockaddr_in *)&rt.rt_genmask)->sin_addr)<0)
    {
      printf( "addRoute:  mask inet_aton error\n" );
      rc = -4;
      break;
    }
 
    if(devName)
      rt.rt_dev = devName;
    rt.rt_flags = RTF_GATEWAY;
    if (ioctl(fd, SIOCADDRT, &rt)<0)
    {
      printf( "ioctl(SIOCADDRT) error in set_route\n");
      rc = -5;
    }
  }while(0);
 
  close(fd);
#endif//_WINDOWS_
  return rc;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1642965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3-element-plus表格

一、element-plus 1.用组件属性实现跳转路由 <el-menu active-text-color"#ffd04b" background-color"#232323" :default-active"$route.path" //高亮 text-color"#fff"router><el-menu-item index"/article/channe…

基于yolov2深度学习网络模型的鱼眼镜头中人员检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 load yolov2.mat% 加载训练好的目标检测器 img_size [448,448]; imgPath test/; % 图像…

力扣每日一题105:从前序与中序序列构造二叉树

题目 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,1…

nerf(一)

神经辐射场的概念 辐射场&#xff1a;由光源发出的光线在场景中的传播和反射过程中所形成的能量分布 神经辐射场&#xff1a;用神经网络储存空间位置向任意方向的辐射 定义 说明图&#xff1a; 公式 对于神经网路图的结构说明&#xff1a; 结构图&#xff1a; 空间位置…

clang:在 Win10 上编译 MIDI 音乐程序(二)

先从 Microsoft C Build Tools - Visual Studio 下载 1.73GB 安装 "Microsoft C Build Tools“ 访问 Swift.org - Download Swift 找到 Windows 10&#xff1a;x86_64 下载 swift-5.10-RELEASE-windows10.exe 大约490MB 建议安装在 D:\Swift\ &#xff0c;安装后大约占…

webassembly入门详解(C++)

一、环境配置 环境说明,操作系统为window操作系统。 1.1 下载和安装python 下载 需要python版本至少3.6版本 python下载地址:https://www.python.org/getit/ 安装 检测安装结果 win+R组合键->cmd->输入python->回车 1.2 下载和安装emsdk 下载 下载地址:https://gi…

jQuery 学习归纳1 --- jQuery 常用API

jQuery其实就是一个Js文件&#xff0c;里面集合了很多封装好的函数。方便了我们进行开发使用。 使用jQuery&#xff0c;就是为了更快速操作DOM。 一、jQuery前期准备 1.1 jQuery 使用的前期准备 在使用之前需要需要在项目中导入jQuery文件。 1、进入jQuery官网 www.jQuery.co…

支付宝支付流程

第一步前端&#xff1a;点击去结算&#xff0c;前端将商品的信息传递给后端&#xff0c;后端返回一个商品的订单号给到前端&#xff0c;前端将商品的订单号进行存储。 对应的前端代码&#xff1a;然后再跳转到支付页面 // 第一步 点击去结算 然后生成一个订单号 // 将选中的商…

计算机专业就业前景以及工资待遇水平怎么样

计算机专业毕业生的就业前景不错的&#xff0c;计算机专业人才的需求量大&#xff0c;各行各业都需要这类人才来进行软件开发、数据分析、网络安全管理、系统维护等工&#xff0c;工资待遇水平较高&#xff0c;以下是上大学网&#xff08;www.sdaxue.com)整理的计算机专业就业前…

手把手教你在本机安装Stable Diffusion秋叶整合包(附安装包和大模型)

整合包对非技术出身的同学比较友好&#xff0c;因为秋叶大佬把相关的东西已经都整合好了&#xff0c;只需要点点点就行了。当然懂编程的同学就更没有问题了。 文末领取SD安装包和大模型&#xff01; 准备 为了保证AI绘画的效率&#xff0c;建议在本机安装Nvidia独立显卡&…

转速(RPM)和角速度转换FC(CODESYS ST代码)

1、频率和转速转换功能块 频率和转速转换功能块(CODESYS ST源代码)-CSDN博客文章浏览阅读16次。1、转速和频率转换功能块转速和频率转换功能块(CODESYS ST源代码)-CSDN博客文章浏览阅读10次。1、转速/频率常用转换关系转速/频率/线速度/角速度计算FC_200 plc计算角速度-CSDN博…

EXCEL怎样把筛选后含有公式的数据,复制粘贴到同一行的其它列?

自excel2003版之后&#xff0c;常规情况下&#xff0c;复制筛选后的数据&#xff0c;会忽略隐藏行&#xff0c;仅复制其筛选后的数据&#xff0c;粘贴则是粘贴到连续单元格区域&#xff0c;不管行是在显示状态还是隐藏状态。 一、初始数据&#xff1a; 二、题主的复制粘贴问题…

Android仿微信公众号文章页面加载进度条

前言&#xff1a; 微信公众号文章详情页面加载的时候&#xff0c;WebView会在头部显示一个进度条&#xff0c;这样做的好处就是用户可以一边加载网页内容的同时也可浏览网页内容&#xff0c;不需要等完全加载完之后才全部显示出来。如何实现呢&#xff1f; 其实很简单&#xf…

【机器学习】BK- SDM与LCM的融合策略在文本到图像生成中的应用

突破边缘设备限制&#xff1a;BK-SDM与LCM的融合策略在文本到图像生成中的应用 一、引言二、稳定扩散算法的挑战与现状三、BK-SDM与LCM的融合策略利用高质量图像-文本对进行训练为LCM量身定制高级蒸馏过程 四、结论与展望 一、引言 随着人工智能技术的飞速发展&#xff0c;文本…

www.fastssh.com SSH over WebSockets with CDNs

https://www.fastssh.com/page/create-ssh-cdn-websocket/server/这其实不是标准的websocket报文(服务器响应报文无Sec-Websocket-Accept字段)&#xff0c;所以无法使用github.com/gorilla/websocket包&#xff1a;GET / HTTP/1.1 Host: hostname:8080 User-Agent: Go-http-cli…

c#学习基础1

一、复杂数据类型 1&#xff09;概述 2&#xff09;枚举 1.基本概念 枚举是一个比较特别的存在&#xff0c;它是一个被命名的整形常量的集合&#xff0c;一般用它来表示状态&#xff0c;类型等 1.1申明枚举和申明枚举变量 1.2申明枚举语法 2.在哪里申明枚举 3.枚举的使用 4…

Unity技术学习:RenderMesh、RenderMeshInstanced

叠甲&#xff1a;本人比较菜&#xff0c;如果哪里不对或者有认知不到的地方&#xff0c;欢迎锐评&#xff08;不玻璃心&#xff09;&#xff01; 导师留了个任务&#xff0c;渲染大量的、移动的物体。 当时找了几个解决方案&#xff1a; 静态批处理&#xff1a; 这东西只对静…

从0开始linux(1)——文件操作

欢迎来到博主的专栏——从0开始linux 博主ID&#xff1a;代码小豪 博主使用的linux发行版是&#xff1a;CentOS 7.6 不同版本下的操作可能存在差异 文章目录 命令文件操作命令文件树和文件路径文件树绝对路径相对路径 文件属性tree指令删除文件复制文件 大家还记得在小学第一次…

java下乡扶贫志愿者招募管理系统springboot-vue

计算机技术在现代管理中的应用&#xff0c;使计算机成为人们应用现代技术的重要工具。能够有效的解决获取信息便捷化、全面化的问题&#xff0c;提高效率。 技术栈 前端&#xff1a;vue.jsElementUI 开发工具&#xff1a;IDEA 或者eclipse都支持 编程语言: java 框架&#xff1…

SQL 基础 | AVG 函数的用法

在SQL中&#xff0c;AVG()是一个聚合函数&#xff0c;用来计算某个列中所有值的平均值。 它通常与GROUP BY子句一起使用&#xff0c;以便对分组后的数据进行平均值计算。 AVG()函数在需要了解数据集中某个数值列的中心趋势时非常有用。 以下是AVG()函数的一些常见用法&#xff…