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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发仿咸鱼TabBar

鸿蒙开发自定义TabBar&#xff0c;实现tabBar 上中间按钮凸起效果 第一步、定义数据模型 export default class TabItemData{defaultIcon: ResourceselectedIcon: Resourcetitle: stringisMiddle: booleanconstructor(defaultIcon:Resource, selectedIcon:Resource, title:st…

5分钟速通大语言模型(LLM)的发展与基础知识

✍️ 作者&#xff1a;哈哥撩编程&#xff08;视频号同名&#xff09; 博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5; 程序员&#xff1a;职场关键角色通识宝…

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

Java发送请求-http+https的

第一步&#xff1a;建议ssl连接对象&#xff0c;信任所有证书 第二步&#xff1a;代码同时支持httphttps 引入源码类 是一个注册器 引入这个类&#xff0c;和它的方法create 注册器&#xff0c;所以对http和https都进行注册&#xff0c;参数为id和item&#xff0c;其中http的…

WebAssembly 入门教程 c++、python编译wasm

WebAssembly 入门 了解 wasm 使用场景&#xff0c;复杂对象传递和经验法则。 简介 WebAssembly 是一种新的编码方式&#xff0c;可以在现代的网络浏览器中运行。它是一种低级的类汇编语言&#xff0c;具有紧凑的二进制格式&#xff0c;可以接近原生的性能运行&#xff0c;并…

c#学习基础1

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

【网络编程下】五种网络IO模型

目录 前言 一.I/O基本概念 1.同步和异步 2.阻塞和非阻塞 二.五种网络I/O模型 1.阻塞I/O模型 2.非阻塞式I/O模型 ​编辑 3.多路复用 4.信号驱动式I/O模型 5. 异步I/O模型 三.五种I/O模型比较​编辑 六.I/O代码示例 1. 阻塞IO 2.非阻塞I/O 3.多路复用 (1)select …

Llama 3 安装使用方法

Llama3简介&#xff1a; llama3是一种自回归语言模型&#xff0c;采用了transformer架构&#xff0c;目前开源了8b和70b参数的预训练和指令微调模型&#xff0c;400b正在训练中&#xff0c;性能非常强悍&#xff0c;并且在15万亿个标记的公开数据进行了预训练&#xff0c;比ll…

Leetcode—422. 有效的单词方块【简单】Plus

2024每日刷题&#xff08;126&#xff09; Leetcode—422. 有效的单词方块 实现代码 class Solution { public:bool validWordSquare(vector<string>& words) {int row words.size();for(int i 0; i < row; i) {// 当前这一行的列数int col words[i].length(…

Postman的一些使用技巧

Postman 是一个流行的 API 开发工具&#xff0c;用于设计、开发、测试、发布和监控 API。在现代web开发中使用非常广泛。后端开发必备而且必会的工具。 目录 1.配置环境变量 2.动态变量 3.脚本 4.测试 5.模拟 6.监控 7.集合运行器 8.响应保存 9.请求历史 10.同步请求…

如何在iPhone上恢复出厂设置后恢复数据

你不想让这种情况发生&#xff0c;但它确实发生了。您必须将iPhone恢复出厂设置。当您的 iPhone 上出现软件问题且无法修复时&#xff0c;可能会发生这种情况。相反&#xff0c;在更新期间&#xff0c;或者您的iPhone遇到问题时&#xff0c;iPhone上的数据不再存在。 不过不用…

leetcode_47.全排列 II

47. 全排列 II 题目描述&#xff1a;给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]]示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] …

性能优化(一):ArrayList还是LinkedList?

引言 集合作为一种存储数据的容器&#xff0c;是我们日常开发中使用最频繁的对象类型之一。JDK为开发者提供了一系列的集合类型&#xff0c;这些集合类型使用不同的数据结构来实现。因此&#xff0c;不同的集合类型&#xff0c;使用场景也不同。 很多同学在面试的时候&#x…

Flutter笔记:使用Flutter私有类涉及的授权协议问题

Flutter笔记 使用Flutter私有类涉及的授权协议问题 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.cs…

使用docker-compose编排lnmp(dockerfile)完成wordpress

文章目录 使用docker-compose编排lnmp&#xff08;dockerfile&#xff09;完成wordpress1、服务器环境2、Docker、Docker-Compose环境安装2.1 安装Docker环境2.2 安装Docker-Compose 3、nginx3.1 新建目录&#xff0c;上传安装包3.2 编辑Dockerfile脚本3.3 准备nginx.conf配置文…

【哈希表】Leetcode 14. 最长公共前缀

题目讲解 14. 最长公共前缀 算法讲解 我们使用当前第一个字符串中的与后面的字符串作比较&#xff0c;如果第一个字符串中的字符没有出现在后面的字符串中&#xff0c;我们就直接返回&#xff1b;反之当容器中的所有字符串都遍历完成&#xff0c;说明所有的字符串都在该位置…

Java枚举(enum)

“今天我们来学习枚举吧&#xff0c;三妹&#xff01;”我说&#xff0c;“同学让你去她家玩了两天&#xff0c;感觉怎么样呀&#xff1f;” “心情放松了不少。”三妹说&#xff0c;“可以开始学 Java 了&#xff0c;二哥。” “OK。” “枚举&#xff08;enum&#xff09;…

Linux服务器安全基础 - 查看入侵痕迹

1. 常见系统日志 /var/log/cron 记录了系统定时任务相关的日志 /var/log/dmesg 记录了系统在开机时内核自检的信息&#xff0c;也可以使用dmesg命令直接查看内核自检信息 /var/log/secure:记录登录系统存取数据的文件;例如:pop3,ssh,telnet,ftp等都会记录在此. /var/log/btmp:记…

【数据结构】链表专题2

前言 本篇博客继续探讨有关链表的专题&#xff0c;这片博客的题&#xff0c;提前打个预防针&#xff0c;有点意思哦&#xff0c;哈哈哈&#xff0c;话不多说&#xff0c;进入正文 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论…

ubuntu下安装配置python3.11

方案1 添加仓库&#xff1a; $ sudo add-apt-repository ppa:deadsnakes/ppa $ sudo apt update $ sudo apt install python3.11然后查看有多少个python版本已经安装了&#xff1a; ls -l /usr/bin/python*python2.7,python 3.8 ,python 3.11. 然后&#xff0c;设置系统默认…