網絡拓撲如下所示:
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]信息可以忽略。