SDK(IPC)遠程調用之模擬網關轉發信令[內網穿透小Demo]

網絡拓撲如下所示:

SwitchTest.cpp(轉發程序)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>

#define SERVER_IP "127.0.0.1"
#define CLIENT_IP "192.168.8.250"
#define SERVER_PORT 8080 //接收端口
#define CLIENT_PORT 8000 //發送端口
#define MAXLINE 2048

using namespace std;    

pthread_t recvThd;
pthread_t sendThd;
int listenfd;
int recv_sockfd,send_sockfd,n,m;
unsigned char recvBuf[MAXLINE];
unsigned char rstBuf[MAXLINE]; 
sockaddr_in server_addr,client_addr;  

void *recv_threadFun(void *args){
     
    while(1){
       printf("recv msg from client:\n");
        n = recv(recv_sockfd,recvBuf,MAXLINE,0);        //接收SDK調用者發送過來的數據
        if(n==0) break;
        recvBuf[n] = '\0';
        printf("%d\n",n);
        for(int i = 0;i<n;i++){
            if(i%8 == 0 && i!=0) printf("\n"); 
            printf("%02X ",recvBuf[i]);
        }
        printf("\n"); 

        printf("send msg to IPC:\n");
        if ( send(send_sockfd,recvBuf,n,0) < 0 ) {    //將數據轉發給IPC
		    printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
		    return 0;
	    }
        memset(recvBuf,0,sizeof(recvBuf)/sizeof(char));
    }
    

}

void *send_threadFun(void *args){
    
    while(1){
        printf("recv msg from IPC:\n");
        m = recv(send_sockfd,rstBuf,MAXLINE,0);       //接收從IPC返回的數據
        rstBuf[m] = '\0';
        printf("%d\n",m);
        for(int i = 0;i<m;i++){
            if(i%8 == 0 && i!=0) printf("\n"); 
            printf("%02X ",rstBuf[i]);
        }
        printf("\n");

        printf("send msg to client:\n");
        if ( send(recv_sockfd,rstBuf,m,0) < 0 ) {       //將SDK調用結果返回給SDK調用者
		    printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
		    return 0;
	    }
        memset(rstBuf,0,sizeof(rstBuf)/sizeof(char));
    }
}

int main()
{
    int flag1,flag2;

    //接收設置
    if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
		    return 0;
    }
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if(bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr))==-1){
        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }
    if(listen(listenfd,10) == -1){
        printf("listen socket error:%s(errno: %d)\n",strerror(errno),errno);
        return 0;
    }
    recv_sockfd = accept(listenfd,(struct sockaddr*)NULL,NULL);
    if( recv_sockfd == -1){
            printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
    }

    //發送設置
    if((send_sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
		    return 0;
    }
    memset(&client_addr,0,sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(CLIENT_PORT);
    client_addr.sin_addr.s_addr = inet_addr(CLIENT_IP);
    if(connect(send_sockfd,(struct sockaddr *)&client_addr,sizeof(struct sockaddr_in)) == -1){
        printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
		    return 0;
    }

    //開啓兩個線程
    flag1 = pthread_create(&recvThd,NULL,recv_threadFun,NULL);
    flag2 = pthread_create(&sendThd,NULL,send_threadFun,NULL);
    pthread_join(recvThd,NULL);
    pthread_join(sendThd,NULL);

    close(listenfd);
    close(recv_sockfd);
    close(send_sockfd);

    return 0;
}

consoleMain.cpp(此爲海康SDK的consoleDemo,在linux64位下make,此處更改了目的端口號8080(默認爲8000),目的地址127.0.0.1(默認爲IPC地址))

#ifndef __APPLE__

#include <stdio.h>
#include <iostream>
#include "GetStream.h"
#include "public.h"
#include "ConfigParams.h"
#include "Alarm.h"
#include "CapPicture.h"
#include "playback.h"
#include "Voice.h"
#include "tool.h"
#include <string.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

using namespace std;

int main()
{
    NET_DVR_Init();
    Demo_SDK_Version();
    NET_DVR_SetLogToFile(3, "/home/zzg/consoleDemo/linux64/proj/sdkLog");
    char cUserChoose = 'r'; 
    //Login device
    NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
    NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};
    struLoginInfo.bUseAsynLogin = false;

    struLoginInfo.wPort = 8080;//
    memcpy(struLoginInfo.sDeviceAddress, "127.0.0.1", NET_DVR_DEV_ADDRESS_MAX_LEN);//
    memcpy(struLoginInfo.sUserName, "admin", NAME_LEN);
    memcpy(struLoginInfo.sPassword, "iot123456", NAME_LEN);
    printf("*************begin\n");
    int lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
    printf("*************end\n");
    if (lUserID < 0)
    {
        printf("pyd---Login error, %d\n", NET_DVR_GetLastError());
        printf("Press any key to quit...\n");
        cin>>cUserChoose;

        NET_DVR_Cleanup();
        return HPR_ERROR;
    }
    // NET_DVR_SDKSTATE struStatInfo = {0};    
    // BOOL stat = NET_DVR_GetSDKState(&struStatInfo);
    // printf("The sdk stat is %d\n",stat);
    // printf("The login num are %d\n",struStatInfo.dwTotalLoginNum);

    // NET_DVR_DEVICECFG_V50 m_struDeviceCfgV50; 
    // m_struDeviceCfgV50.sSerialNumber;

    // if ('q' != cUserChoose)
    // {
    //     printf("\n");
    //     printf("Input 1, Test GetStream\n");
    //     printf("      2, Test Configure params\n");
    //     printf("      3, Test Alarm\n");
    //     printf("      4, Test Capture Picture\n");
    //     printf("      5, Test play back\n");
    //     printf("      6, Test Voice\n");
    //     printf("      7, Test SDK ability\n");
    //     printf("      8, Test tool interface\n");
    //     cUserChoose='1';
    //     switch (cUserChoose)
    //     {
    //     case '1':
    //         Demo_GetStream_V30(lUserID); //Get stream.
    //         break;
    //     case '2':
    //         Demo_ConfigParams(lUserID);  //Setting params.
    //         break;
    //     case '3':
    //         Demo_Alarm();         //Alarm & listen.
    //         break;
    //     case '4':
    //         Demo_Capture();
    //         break;
    //     case '5':
    //         Demo_PlayBack((int)lUserID);     //record & playback
    //         break;
    //     case '6':
    //         Demo_Voice();
    //         break;
    //     case '7':
    //         Demo_SDK_Ability();
    //         break;
	// 	case '8':
	// 		Demo_DVRIPByResolveSvr();
	// 		break;
    //     default:
    //         break;
    //     }
    // }
    NET_DVR_Logout_V30(lUserID);
    NET_DVR_Cleanup();
    return 0;
}

#endif

此demo只驗證了登錄功能,據此可以表明轉發成功。結果如下所示:

上圖中幾個[ERR]信息可以忽略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章