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

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

产品AB测试设计

因为vue2项目升级到vue3经历分享1&#xff0c;vue2项目升级到vue3经历分享2&#xff0c;前端系统升级&#xff0c;界面操作也发生改变&#xff0c;为了将影响降到最低&#xff0c;是不能轻易让所有用户使用新系统的。原系统使用好好的&#xff0c;如果新界面用户不喜欢&#xf…

2024/5/5 英语每日一段

Meanwhile, in a twist, Tesla this month settled a high-profile case in Northern California that claimed Autopilot played a role in the fatal crash of an Apple engineer, Walter Huang. The company’s decision to settle with Huang’s family—along with a ruli…

如何打包Apk适配32和64位

一个表格了解lib下的文件夹 .so文件描述armeabi-v7a第七代及以上的ARM处理器&#xff0c;2011年以后生产的大部分Android设备都使用。arm64-v8a第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星GalaxyS6是其中之一。armeabi第5代、第6代的ARM处理器&#xff0c;早期…

Mysql报错红温集锦(一)(ipynb配置、pymysql登录、密码带@、to_sql如何加速、触发器SIGNAL阻止插入数据)

一、jupyter notebook无法使用%sql来添加sql代码 可能原因&#xff1a; 1、没装jupyter和notebook库、没装ipython-sql库 pip install jupyter notebook ipython-sql 另外如果是vscode的话还需要安装一些相关的插件 2、没load_ext %load_ext sql 3、没正确的登录到mysql…

Git-flow分支管理与Aone-flow分支管理对比

Git-flow分支管理与Aone-flow分支管理对比 git-flow分支管理&#xff1a; master: 主分支&#xff0c;主要用来版本发布。 hotfix&#xff1a;线上 bug 紧急修复用到的临时分支。这个分支用来修复主线master的BUG release&#xff08;预发布分支&#xff09;&#xff1a;rel…

深入理解网络原理2----UDP协议

文章目录 前言一、UDP协议协议段格式&#xff08;简图&#xff09;校验和 二、UDP与TCP 前言 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同⼯作来完成业务&#xff0c;就有了⽹络互连。 一、UDP协议 协…

基于matlab GUI的Alpha shapes边缘提取

1、程序介绍 本程序是基于matlab语言&#xff0c;使用alpha shapes算法实现点云边缘提取。算法具体原理参考博客&#xff1a;基于alpha shapes的边缘点提取&#xff08;matlab&#xff09;-CSDN博客。该程序包括3个按钮&#xff1a;加载点云、边缘点提取、保存。其中&#xff0…

A Bug‘s Life (并查集)

//新生训练 #include <iostream> #include <algorithm> using namespace std; const int N 5000; int p[N], sz[N]; int n, m; int find(int x) {if (p[x] ! x)p[x] find(p[x]);return p[x]; } int main() {int T;scanf("%d", &T);for (int k 1; …

c#学习基础1

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

13_Scala面向对象编程_伴生对象

文章目录 1.伴生对象1.1 scala的一个性质&#xff0c;scala文件中的类都是公共的&#xff1b;1.2 scala使用object关键字也可以声明对象&#xff1b; 3.关于伴生对象和类4.权限修饰符&#xff0c;scala仅有private;5.伴生对象可以访问伴生类中的私有属性&#xff1b;6.案例7.伴…

五一假期告别人山人海,AI绘画让你的照片更美!

快乐总是短暂的&#xff0c;五一假期结束了&#xff0c;想必大家都拍了不少好看的照片&#xff0c;但是景点也经常是人山人海&#xff0c;照片中不免会出现其它不相干的人或物&#xff0c;以前想抹除这些人或物得找专业的美工或者图像处理专家P掉才行&#xff0c;现在AI绘画来了…

【Redis】Redis命令(一)

1.基本命令 1.1.切换DB 默认使用的是 0 号 DB&#xff0c;可以通过 select db 索引来切换 DB 1.2.查看 key 数量 dbsize 命令可以查看当前数据库中 key 的数量 1.3.删除当前库中数据 flushdb 命令仅仅删除的是当前数据库中的数据&#xff0c;不影响其它库 1.4.删除所有库中数据…

用Python做多项Logit模型

看到网上有一些用 python 做多项 Logit 模型的讲解&#xff0c;大多是使用 scikit-learn 库。这里要介绍的是如何使用 statsmodels 库来做多项 Logit 模型。 题外话&#xff0c;有人会问&#xff0c;statsmodels 和 scikit-learn 两个库有什么区别&#xff1f;为什么你非要用 …

SQL 基础 | JOIN 操作介绍

在SQL中&#xff0c;JOIN是一种强大的功能&#xff0c;用于将两个或多个表中的行结合起来&#xff0c;基于相关的列之间的关系。 JOIN操作通常用在SELECT语句中&#xff0c;以便从多个表中检索数据。 以下是几种基本的JOIN类型以及它们的用法&#xff1a; INNER JOIN&#xff1…

数据结构===树

文章目录 概要概念相关概念 有哪些常用的树小结 概要 树是一种新的数据结构&#xff0c;不同于数组&#xff0c;链表。就像大自然中的树&#xff0c;看下这个数据结构&#xff0c;很有意思&#xff0c;有一个主干&#xff0c;然后还有很多树叉&#xff0c;即支干。不错&#xf…

数据结构练习题---环形链表详解

链表成环&#xff0c;在力扣中有这样的两道题目 https://leetcode.cn/problems/linked-list-cycle/ https://leetcode.cn/problems/linked-list-cycle-ii/description/ 这道题的经典解法是利用快慢指针&#xff0c;如果链表是一个环形链表&#xff0c;那么快指针(fast)和慢指…

求矩阵对角线元素之和(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 0;int j 0;int sum 0;int a[3][3] { 0 };//获取数组a的值&#xff1b;printf(&qu…

华为鸿蒙系统(Huawei HarmonyOS)

华为鸿蒙系统&#xff08;华为技术有限公司开发的分布式操作系统&#xff09; 华为鸿蒙系统&#xff08;HUAWEI HarmonyOS&#xff09;&#xff0c;是华为公司在2019年8月9日于东莞举行的华为开发者大会&#xff08;HDC.2019&#xff09;上正式发布的分布式操作系统。 华为鸿蒙…

STM32单片机实战开发笔记-I2C通讯总线【wulianjishu666】

嵌入式单片机开发实战例程合集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11av8rV45dtHO0EHf8e_Q0Q?pwd28ab 提取码&#xff1a;28ab I2C模块测试 功能描述 I2C总线接口连接微控制器和串行I2C总线。它提供多主机功能&#xff0c;控制所有I2C总线特定的时序&am…

QCC3071/QCC3081/QCC3083/QCC3084/QCC5171/QCC5181/QCC3091/QCC3095平台LDAC解码

QCC3071/QCC3081/QCC3083/QCC3084/QCC5171/QCC5181/QCC3091/QCC3095平台LDAC解码 LDAC Decoder Evaluation Kit for QCC5181 and QCC5171 (The 5181 Kit) 随着Qualcomm DSP向下开放&#xff0c;QCC3071/QCC3081/QCC3083/QCC3084目前可以可以实现LDAC Decoder。 QCC3071/QCC3…