使用socket多线程多客户端传输信号

一、需求

        需要将一个c++可执行文件中的两个信号实时传送给两个不同的C++可执行文件

服务端: 

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
//#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include<signal.h>
#include<iostream>
#include <cstring>

//服务器端
 
void *fun_thrReceiveHandler(void *socketInfo);
void *fun_thrAcceptHandler(void *socketListen);
//1:是 0:否
int checkThrIsKill(pthread_t thr);
 
typedef struct MySocketInfo{
    int socketCon;
    char *ipaddr;
    uint16_t port;
}_MySocketInfo;
 
// 客户端数组
struct MySocketInfo arrConSocket[10];
int conClientCount = 0;
 
// 接受客户端线程列表
pthread_t arrThrReceiveClient[10];
int thrReceiveClientCount = 0;
 
int main()
{
    //初始化全局变量
    //memset(arrConSocket,0,sizeof(struct MySocketInfo)*10);
 
    printf("开始socket\n");
    /* 创建TCP连接的Socket套接字 */
    int socketListen = socket(AF_INET, SOCK_STREAM, 0);
    if(socketListen < 0){
        printf("创建TCP套接字失败\n");
        exit(-1);
    }else{
        printf("创建套接字成功\n");
    }
    /* 填充服务器端口地址信息,以便下面使用此地址和端口监听 */
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY); /* 这里地址使用全0,即所有 */
    server_addr.sin_port=htons(2000);
    if(bind(socketListen, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) != 0){
        perror("绑定ip地址、端口号失败\n");
        exit(-1);
    }else{
        printf("绑定ip地址,端口号\n");
    }
    /* 开始监听相应的端口 */
    if(listen(socketListen, 10) != 0){
        printf("开启监听失败\n");
        exit(-1);
    }else{
        printf("开启监听成功\n");
    }
    /* 接受连接套接字 */
    pthread_t thrAccept;
    pthread_create(&thrAccept,NULL,fun_thrAcceptHandler,&socketListen);
 
    /* 实时发送数据 */
    while(1){
        //判断线程存活多少
        int i;
        for(i=0;i<thrReceiveClientCount;i++){
            if(checkThrIsKill(arrThrReceiveClient[i]) == 1){
                printf("有个线程被杀了\n");
                thrReceiveClientCount--;
            }
        }
        printf("当前有接受数据线程多少个:%d\n",thrReceiveClientCount);
 
        // 可以录入用户操作选项,并进行相应操作
        char userStr[30] = {'0'};
        scanf("%s",userStr);
        if(strcmp(userStr,"q") == 0){
            printf("用户选择退出!\n");
            break;
        }
        // 发送消息
        if(conClientCount <= 0){
            printf("没有客户端连接\n");
        }else{
            int i;
            for(i=0; i<conClientCount; i++){
                //int sendMsg_len = send(arrConSocket[i].socketCon, userStr, 30, 0);
				std::cout << "arrConSocket[i].socketCon" << arrConSocket[i].socketCon << std::endl;
                int sendMsg_len = write(arrConSocket[i].socketCon,userStr,30);
                if(sendMsg_len > 0){
                    printf("向%s:%d发送成功\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
					std::cout << "arrConSocket[i].ipaddr" << arrConSocket[i].ipaddr << std::endl;
					std::cout << "arrConSocket[i].port" << arrConSocket[i].port << std::endl;
                }else{
                    printf("向%s:%d发送失败\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
                }
            }
        }
 
        sleep(0.5);
    }
 
    // 等待子进程退出
    printf("等待子线程退出,即将退出!\n");
    //char *message;
	void * a;
    pthread_join(thrAccept,&a);
    printf("%s\n",a);
 
    return 0;
}
 
void *fun_thrAcceptHandler(void *socketListen){
    while(1){
        int sockaddr_in_size = sizeof(struct sockaddr_in);
        struct sockaddr_in client_addr;
        int _socketListen = *((int *)socketListen);
        int socketCon = accept(_socketListen, (struct sockaddr *)(&client_addr), (socklen_t *)(&sockaddr_in_size));
        if(socketCon < 0){
            printf("连接失败\n");
        }else{
            printf("连接成功 ip: %s:%d\r\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
        }
        printf("连接套接字为:%d\n",socketCon);
        //开启新的通讯线程,负责同连接上来的客户端进行通讯
        _MySocketInfo socketInfo;
        socketInfo.socketCon = socketCon;
        socketInfo.ipaddr = inet_ntoa(client_addr.sin_addr);
        socketInfo.port = client_addr.sin_port;
        arrConSocket[conClientCount] = socketInfo;
        conClientCount++;
        printf("连接了%d个用户\n",conClientCount);
 
        pthread_t thrReceive = 0;
        pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketInfo);
        arrThrReceiveClient[thrReceiveClientCount] = thrReceive;
        thrReceiveClientCount++;
 
        //让进程休息1秒
        sleep(0.5);
    }
 
    char *s = "安全退出接受进程";
    pthread_exit(s);
}
 
void *fun_thrReceiveHandler(void *socketInfo){
	char buffer[30];
	int aa;
	int cc;
	int buffer_length;
	_MySocketInfo _socketInfo = *((_MySocketInfo *)socketInfo);
    while(1){
    	//添加对buffer清零
    	bzero(&buffer,sizeof(buffer));
 
        buffer_length = read(_socketInfo.socketCon,buffer,30);
        if(buffer_length == 0){
            printf("%s:%d 客户端关闭\n",_socketInfo.ipaddr,_socketInfo.port);
            conClientCount--;
            break;
        }else if(buffer_length < 0){
            printf("接受客户端数据失败\n");
            break;
        }
        buffer[buffer_length] = '\0';
        printf("%s:%d 说:%s\n",_socketInfo.ipaddr,_socketInfo.port,buffer);
		std::string message1 = "Hello, client11111!";
		std::string message2 = "Hello, client22222!";
		std::cout << "buffer = " << buffer << std::endl;
		cc = atoi(buffer);
		//sprintf(buffer,"%f",aa);
		std::cout << "cc = " << cc << std::endl; 
		
		if(cc == 1)
			buffer_length = write(_socketInfo.socketCon, message1.c_str(), message1.length() + 1);
		if(cc == 2)
			buffer_length = write(_socketInfo.socketCon, message2.c_str(), message2.length() + 1);
 
        sleep(0.2);
    }
    printf("接受数据线程结束了\n");
    return NULL;
}
 
int checkThrIsKill(pthread_t thr){
    int res = 1;
    int res_kill = pthread_kill(thr,0);
    if(res_kill == 0){
        res = 0;
    }
    return res;
}

 客户端1:

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include<signal.h>
 
typedef struct MySocketInfo{
    int socketCon;
    unsigned long ipaddr;
    unsigned short port;
}_MySocketInfo;
 
void *fun_thrReceiveHandler(void *socketCon);
int checkThrIsKill(pthread_t thr);
 
int main()
{
    printf("开始socket\n");
    /* 创建TCP连接的Socket套接字 */
    int socketCon = socket(AF_INET, SOCK_STREAM, 0);
    if(socketCon < 0){
        printf("创建TCP连接套接字失败\n");
        exit(-1);
    }
    /* 填充客户端端口地址信息,以便下面使用此地址和端口监听 */
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); /* 这里地址使用全0,即所有 */
    server_addr.sin_port=htons(2000);
    /* 连接服务器 */
    int res_con = connect(socketCon,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
    if(res_con != 0){
        printf("连接失败\n");
        exit(-1);
    }
    printf("连接成功,连接结果为:%d\n",res_con);
    //开启新的实时接受数据线程
    pthread_t thrReceive;
    pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketCon);
 
    /* 实时发送数据 */
    while(1){
        //检测接受服务器数据线程是否被杀死
 	sleep(2);
 
        char userStr[30] = {'2'};
        // 可以录入用户操作选项,并进行相应操作
        //scanf("%s",userStr);
        if(strcmp(userStr,"q") == 0){
            printf("用户选择退出!\n");
            break;
        }
        // 发送消息
        //int sendMsg_len = send(socketCon, userStr, 30, 0);
        int sendMsg_len = write(socketCon,userStr,30);
        if(sendMsg_len > 0){
            printf("发送成功,服务端套接字句柄:%d\n",socketCon);
        }else{
            printf("发送失败\n");
        }
 
        //if(checkThrIsKill(thrReceive) == 1){
            //printf("接受服务器数据的线程已被关闭,退出程序\n");
            //break;
        //}
    }
    // 关闭套接字
    close(socketCon);
    return 0;
}
 
void *fun_thrReceiveHandler(void *socketCon){
    while(1){
        char buffer[30];
        int _socketCon = *((int *)socketCon);
        //int buffer_length = recv(_socketCon,buffer,30,0);
        int buffer_length = read(_socketCon,buffer,30);
        if(buffer_length == 0){
            printf("服务器端异常关闭\n");
            exit(-1);
        }else if(buffer_length < 0){
            printf("接受客户端数据失败\n");
            break;
        }
        buffer[buffer_length] = '\0';
        printf("服务器说:%s\n",buffer);
    }
    printf("退出接受服务器数据线程\n");
    return NULL;
}
 
int checkThrIsKill(pthread_t thr){
    int res = 1;
    int res_kill = pthread_kill(thr,0);
    if(res_kill == 0){
        res = 0;
    }
    return res;
}

客户端2:

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

#include<signal.h>
 
typedef struct MySocketInfo{
    int socketCon;
    unsigned long ipaddr;
    unsigned short port;
}_MySocketInfo;
 
void *fun_thrReceiveHandler(void *socketCon);
int checkThrIsKill(pthread_t thr);
 
int main()
{
    printf("开始socket\n");
    /* 创建TCP连接的Socket套接字 */
    int socketCon = socket(AF_INET, SOCK_STREAM, 0);
    if(socketCon < 0){
        printf("创建TCP连接套接字失败\n");
        exit(-1);
    }
    /* 填充客户端端口地址信息,以便下面使用此地址和端口监听 */
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); /* 这里地址使用全0,即所有 */
    server_addr.sin_port=htons(2000);
    /* 连接服务器 */
    int res_con = connect(socketCon,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
    if(res_con != 0){
        printf("连接失败\n");
        exit(-1);
    }
    printf("连接成功,连接结果为:%d\n",res_con);
    //开启新的实时接受数据线程
    pthread_t thrReceive;
    pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketCon);
 
    /* 实时发送数据 */
    while(1){
        //检测接受服务器数据线程是否被杀死
	sleep(2);
 
        char userStr[30] = {'1'};
        // 可以录入用户操作选项,并进行相应操作
        //scanf("%s",userStr);
        if(strcmp(userStr,"q") == 0){
            printf("用户选择退出!\n");
            break;
        }
        // 发送消息
        //int sendMsg_len = send(socketCon, userStr, 30, 0);
        int sendMsg_len = write(socketCon,userStr,30);
        if(sendMsg_len > 0){
            printf("发送成功,服务端套接字句柄:%d\n",socketCon);
        }else{
            printf("发送失败\n");
        }
 
        //if(checkThrIsKill(thrReceive) == 1){
            //printf("接受服务器数据的线程已被关闭,退出程序\n");
            //break;
        //}
    }
    // 关闭套接字
    close(socketCon);
    return 0;
}
 
void *fun_thrReceiveHandler(void *socketCon){
    while(1){
        char buffer[30];
        int _socketCon = *((int *)socketCon);
        //int buffer_length = recv(_socketCon,buffer,30,0);
        int buffer_length = read(_socketCon,buffer,30);
        if(buffer_length == 0){
            printf("服务器端异常关闭\n");
            exit(-1);
        }else if(buffer_length < 0){
            printf("接受客户端数据失败\n");
            break;
        }
        buffer[buffer_length] = '\0';
        printf("服务器说:%s\n",buffer);
    }
    printf("退出接受服务器数据线程\n");
    return NULL;
}
 
int checkThrIsKill(pthread_t thr){
    int res = 1;
    int res_kill = pthread_kill(thr,0);
    if(res_kill == 0){
        res = 0;
    }
    return res;
}

 将上述代码中服务端有两个信号需要传送给上述两个客户端,所以需要客户端传送信号给服务端,让服务端知道是哪个信号传输给哪个客户端。比如客户端1传输信号"1"给服务端,服务端就知道是客户端进行请求,所以传输相应的信号给客户端1,同样的,传输客户端2想要的信号给客户端2

关键代码如下:

服务端

    std::string message1 = "Hello, client11111!";
    std::string message2 = "Hello, client22222!";
	std::cout << "buffer = " << buffer << std::endl;
	cc = atoi(buffer);
	//sprintf(buffer,"%f",aa);
	std::cout << "cc = " << cc << std::endl; 
		
	if(cc == 1)
		buffer_length = write(_socketInfo.socketCon, message1.c_str(), message1.length() + 1);
	if(cc == 2)
		buffer_length = write(_socketInfo.socketCon, message2.c_str(), message2.length() + 1);

客户端1:

    char userStr[30] = {'1'};
    // 可以录入用户操作选项,并进行相应操作
    //scanf("%s",userStr);
    if(strcmp(userStr,"q") == 0){
         printf("用户选择退出!\n");
         break;
     }
     // 发送消息
     //int sendMsg_len = send(socketCon, userStr, 30, 0);
     int sendMsg_len = write(socketCon,userStr,30);

 客户端2:

    char userStr[30] = {'2'};
    // 可以录入用户操作选项,并进行相应操作
    //scanf("%s",userStr);
    if(strcmp(userStr,"q") == 0){
         printf("用户选择退出!\n");
         break;
     }
     // 发送消息
     //int sendMsg_len = send(socketCon, userStr, 30, 0);
     int sendMsg_len = write(socketCon,userStr,30);

在实际应用中服务端还需要创建一个线程,用来生成客户端想要的信号。然后实时传输给客户端。

实列如下:

#include "httplib.h"

#include "HCNetSDK.h"
#include <unistd.h>
#include "LinuxPlayM4.h"
// #include "benchmark.h"
#include "TiltSensor.h"
#include <X11/Xlib.h>

#include "base64.h"
#include "ImgInfo.h"
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <time.h>
#include <json.h>

#include <functional>
#include <queue>
#include <chrono>


#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


//using namespace cv;
using namespace std;
using namespace std::chrono; // calc fps
#include "httplib.h"

float angle;
float result_cam_angle_31;
float result_cam_angle_32;

//服务器端
 
void *fun_thrReceiveHandler(void *socketInfo);
void *fun_thrAcceptHandler(void *socketListen);
//1:是 0:否
int checkThrIsKill(pthread_t thr);
 
typedef struct MySocketInfo{
    int socketCon;
    char *ipaddr;
    uint16_t port;
}_MySocketInfo;
 
// 客户端数组
struct MySocketInfo arrConSocket[10];
int conClientCount = 0;
 
// 接受客户端线程列表
pthread_t arrThrReceiveClient[10];
int thrReceiveClientCount = 0;



void *fun_thrAcceptHandler(void *socketListen){
    while(1){
        int sockaddr_in_size = sizeof(struct sockaddr_in);
        struct sockaddr_in client_addr;
        int _socketListen = *((int *)socketListen);
        int socketCon = accept(_socketListen, (struct sockaddr *)(&client_addr), (socklen_t *)(&sockaddr_in_size));
        if(socketCon < 0){
            printf("连接失败\n");
        }else{
            printf("连接成功 ip: %s:%d\r\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
        }
        printf("连接套接字为:%d\n",socketCon);
        //开启新的通讯线程,负责同连接上来的客户端进行通讯
        _MySocketInfo socketInfo;
        socketInfo.socketCon = socketCon;
        socketInfo.ipaddr = inet_ntoa(client_addr.sin_addr);
        socketInfo.port = client_addr.sin_port;
        arrConSocket[conClientCount] = socketInfo;
        conClientCount++;
        printf("连接了%d个用户\n",conClientCount);
 
        pthread_t thrReceive = 0;
        pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketInfo);
        arrThrReceiveClient[thrReceiveClientCount] = thrReceive;
        thrReceiveClientCount++;
 
        //让进程休息1秒
        sleep(0.5);
    }
 
    char *s = "安全退出接受进程";
    pthread_exit(s);
}



void *fun_thrReceiveHandler(void *socketInfo){
	char buffer[30];
	int aa;
	int cc;
	int buffer_length;
	_MySocketInfo _socketInfo = *((_MySocketInfo *)socketInfo);
    while(1){
    	//添加对buffer清零
    	bzero(&buffer,sizeof(buffer));
 
        buffer_length = read(_socketInfo.socketCon,buffer,30);
        if(buffer_length == 0){
            printf("%s:%d 客户端关闭\n",_socketInfo.ipaddr,_socketInfo.port);
            conClientCount--;
            break;
        }else if(buffer_length < 0){
            printf("接受客户端数据失败\n");
            break;
        }
        buffer[buffer_length] = '\0';
        printf("%s:%d 说:%s\n",_socketInfo.ipaddr,_socketInfo.port,buffer);
		std::string message1 = std::to_string(angle);
		std::string message2 = std::to_string(result_cam_angle_32);
		std::cout << "buffer = " << buffer << std::endl;
		cc = atoi(buffer);
		//sprintf(buffer,"%f",aa);
		std::cout << "cc = " << cc << std::endl; 
		
		if(cc == 1)
			buffer_length = write(_socketInfo.socketCon, message1.c_str(), message1.length() + 1);
		if(cc == 2)
			buffer_length = write(_socketInfo.socketCon, message2.c_str(), message2.length() + 1);
 
        sleep(0.2);
    }
    printf("接受数据线程结束了\n");
    return NULL;
}

int checkThrIsKill(pthread_t thr){
    int res = 1;
    int res_kill = pthread_kill(thr,0);
    if(res_kill == 0){
        res = 0;
    }
    return res;
}




int  HexToDecMa(int wHex)//ʮ������תʮ����
{
    return (wHex / 4096) * 1000 + ((wHex % 4096) / 256) * 100 + ((wHex % 256) / 16) * 10 + (wHex % 16);
}

int DEC2HEX_doc(int x)//ʮ����תʮ������
{
    return (x / 1000) * 4096 + ((x % 1000) / 100) * 256 + ((x % 100) / 10) * 16 + x % 10;
}

void contral_cam(LONG lUserID, int wPanPos1, int wTiltPos1, int wZoomPos1, DWORD dwtmp, NET_DVR_PTZPOS m_ptzPosCurrent){

    bool a = NET_DVR_GetDVRConfig(lUserID, NET_DVR_GET_PTZPOS, 0, &m_ptzPosCurrent, sizeof(NET_DVR_PTZPOS), &dwtmp);
    //转换相机信息到十进制
    int m_iPara1 = HexToDecMa(m_ptzPosCurrent.wPanPos);
    int m_iPara2 = HexToDecMa(m_ptzPosCurrent.wTiltPos);
    int m_iPara3 = HexToDecMa(m_ptzPosCurrent.wZoomPos);
    std::vector<int> TempPosture(3);
    TempPosture[0] = m_iPara1 / 10 ;    //P水平方向
    TempPosture[1] = m_iPara2 / 10 ;    //T仰角
    TempPosture[2] = m_iPara3 / 10 ;    //Z焦距
    
	std::cout << "TempPosture[2] = " << TempPosture[2] << std::endl;
    
    //如果大于1将焦距调到1
    //将俯仰角调到90°
    m_ptzPosCurrent.wPanPos = DEC2HEX_doc(wPanPos1*10);
    m_ptzPosCurrent.wTiltPos = DEC2HEX_doc(wTiltPos1*10);
    m_ptzPosCurrent.wZoomPos = DEC2HEX_doc(wZoomPos1*10);
    
    bool b = NET_DVR_SetDVRConfig(lUserID, NET_DVR_SET_PTZPOS, 0, &m_ptzPosCurrent, sizeof(NET_DVR_PTZPOS));
    sleep(2);
}

//#include "httplib.h"
/*!
 * 通过http请求请教传感器数据
 * x: 倾角传感器数据; 传出参数;
 * y: 倾角传感器数据; 传出参数;
 * return : false, 请求失败或参数解析失败;
 * */
bool function_GetAngle(float &x, float &y) {
    std::cout << "222222222" << std::endl;

    static auto client = httplib::Client("127.0.0.1", 18080);
    auto result = client.Get("/TiltSensor");
    if (!result || result->status != 200) {
        return false;
    }

    auto body = result->body;

    cJSON *root = cJSON_Parse(body.c_str());
    if(!root) {
        return false;
    }

    if(cJSON_GetObjectItem(root, "tilt_x")){
        x = std::abs((float)cJSON_GetObjectItem(root, "tilt_x")->valuedouble);
    } else {
        return false;
    }


    if(cJSON_GetObjectItem(root, "tilt_y")){
        y = (float)cJSON_GetObjectItem(root, "tilt_y")->valuedouble;
    }else {
        return false;
    }

    return true;
}

#include <chrono>
#include <thread>
void gets_angle(){
	//球机信息
    char IP[] = "192.168.8.31";   //����������������ͷ��ip
    char IP_32[] = "192.168.8.32";
    char UName[] = "admin";                 //����������������ͷ���û���
    char PSW[] = "a123456789";

	NET_DVR_Init();
    NET_DVR_SetConnectTime(2000, 1);
    NET_DVR_SetReconnect(1000, true);
    NET_DVR_SetLogToFile(3, "./sdkLog1");
    NET_DVR_DEVICEINFO_V30 struDeviceInfo = { 0 };
    NET_DVR_SetRecvTimeOut(5000);

	LONG lUserID_31 = NET_DVR_Login_V30(IP, 8000, UName, PSW, &struDeviceInfo);
    LONG lUserID_32 = NET_DVR_Login_V30(IP_32, 8000, UName, PSW, &struDeviceInfo);


	//***************************************************************
    //***************************************************************
    //读取配置文件
    Json::Reader reader;
	Json::Value root;
    std::ifstream in("./output.json", std::ios::binary);
    if (!in.is_open())
	{
		std::cout << "Error opening file\n";
	}

    int Pans_31 = 73;
    int Tilts_31 = 90;
    int Zooms_31 = 5;

	int Pans_32 = 48;
    int Tilts_32 = 90;
    int Zooms_32 = 1;

    float standard_bijia_angles_31 = 61.6;  //臂架 Tilt
    float standard_cam_angle_31 = 90; //俯仰角 Tilt
    int standard_cam_Pans_31 = 73; //旋转角  Pan

	float standard_bijia_angles_32 = 61.6;  //臂架 Tilt
    float standard_cam_angle_32 = 89; //俯仰角 Tilt
    int standard_cam_Pans_32 = 48; //旋转角  Pan

    float distance_angle_threshold = 1.0;


    if (reader.parse(in, root))
	{
		Pans_31 = root["Pan_31"].asInt();
        Tilts_31 = root["Tilt_31"].asInt();
        Zooms_31 = root["Zoom_31"].asInt();

		Pans_32 = root["Pan_32"].asInt();
        Tilts_32 = root["Tilt_32"].asInt();
        Zooms_32 = root["Zoom_32"].asInt();

        standard_bijia_angles_31 = root["Tilt_sensor"]["standard_bijia_angles_31"].asFloat();
        standard_cam_angle_31 = root["Tilt_sensor"]["standard_cam_angle_31"].asFloat();
        standard_cam_Pans_31 = root["Tilt_sensor"]["standard_cam_Pans_31"].asInt();

        standard_bijia_angles_32 = root["Tilt_sensor"]["standard_bijia_angles_32"].asFloat();
        standard_cam_angle_32 = root["Tilt_sensor"]["standard_cam_angle_32"].asFloat();
        standard_cam_Pans_32 = root["Tilt_sensor"]["standard_cam_Pans_32"].asInt();


        //const char* net_params = net_para.c_str();
        //const char* net_bins = net_bin.c_str();

		// std::cout << "Pan_31 =  " << Pans_31 << std::endl;
        // std::cout << "Tilt_31 =  " << Tilts_31 << std::endl;
		// std::cout << "Zoom_31 =  " << Zooms_31 << std::endl;

		// std::cout << "Pan_32 =  " << Pans_32 << std::endl;
        // std::cout << "Tilt_32 =  " << Tilts_32 << std::endl;
		// std::cout << "Zoom_32 =  " << Zooms_32 << std::endl;

		// std::cout << "standard_bijia_angles_31 =  " << standard_bijia_angles_31 << std::endl;
		// std::cout << "standard_cam_angle_31 =  " << standard_cam_angle_31 << std::endl;
		// std::cout << "standard_cam_Pans_31 =  " << standard_cam_Pans_31 << std::endl;

		// std::cout << "standard_bijia_angles_32 =  " << standard_bijia_angles_32 << std::endl;
		// std::cout << "standard_cam_angle_32 =  " << standard_cam_angle_32 << std::endl;
		// std::cout << "standard_cam_Pans_32 =  " << standard_cam_Pans_32 << std::endl;

    }
    DWORD dwtmp;
    NET_DVR_PTZPOS m_ptzPosCurrent;

	contral_cam(lUserID_31, standard_cam_Pans_31, Tilts_31, Zooms_31, dwtmp, m_ptzPosCurrent);
    contral_cam(lUserID_32, standard_cam_Pans_32, Tilts_32, Zooms_32, dwtmp, m_ptzPosCurrent);

	//**************************
    //创建倾角传感器
    void* p_TiltSensor_class;
    p_TiltSensor_class = (void*)(new TiltSensor());
    TiltSensor* get_TiltSensor_data = (TiltSensor*)(p_TiltSensor_class);
    get_TiltSensor_data->StartTiltSensor();

	//float angle = 0.0f;
    float angle_y = 0.0f;
    float distance_angle_31;
    float distance_angle_32;

    // float result_cam_angle_31;
    // float result_cam_angle_32;
    float origin_bijia_angles_31 = standard_bijia_angles_31;
    float origin_bijia_angles_32 = standard_bijia_angles_32;

	while(1){

    	sleep(2);
        get_TiltSensor_data->GetTiltData(angle, angle_y);

		std::cout << "angle_x = " << angle << std::endl;
        std::cout << "angle_y = " << angle_y << std::endl;

        result_cam_angle_31 = standard_cam_angle_31 + angle - standard_bijia_angles_31;
        result_cam_angle_32 = standard_cam_angle_32 + angle - standard_bijia_angles_32;

        distance_angle_31 = origin_bijia_angles_31 - angle;
        distance_angle_32 = origin_bijia_angles_32 - angle;
        std::cout << "distance_angle_31 = " << distance_angle_31 << std::endl;
        std::cout << "distance_angle_32 = " << distance_angle_32 << std::endl;
		if(std::abs(distance_angle_31) > distance_angle_threshold){
            origin_bijia_angles_31 = angle;
            origin_bijia_angles_32 = angle;

            std::cout <<"##########change cam angle############";
            //result_cam_angle_31 = standard_cam_angle_31 + angle - standard_bijia_angles_31;
            // result_cam_angle_32 = standard_cam_angle_32 + angle - standard_bijia_angles_32;

            std::cout << "result_cam_angle_31 = " << result_cam_angle_31 << std::endl;
            std::cout << "result_cam_angle_32 = " << result_cam_angle_32 << std::endl;

            //**********************************************
            // sprintf(buffer,"%f",result_cam_angle_31);
            // int n = write(sockfd, buffer, strlen(buffer));
            // if (n < 0) {
            //     perror("Error writing to socket");
            //     break;
            // }
            // memset(buffer, 0, sizeof(buffer));
            // n = read(sockfd, buffer, 1024);
            // if (n < 0) {
            //     perror("Error reading from socket");
            //     break;
            // }
            // cout << "Received message: " << buffer << endl;
            //************************************************
			if (result_cam_angle_31 <= 90){
				contral_cam(lUserID_31, standard_cam_Pans_31, result_cam_angle_31, Zooms_31, dwtmp, m_ptzPosCurrent);
			}
			else{
				contral_cam(lUserID_31, 180 + standard_cam_Pans_31, 180 - result_cam_angle_31, Zooms_31, dwtmp, m_ptzPosCurrent);
			}
			if (result_cam_angle_32 <= 90){
    			contral_cam(lUserID_32, standard_cam_Pans_32, result_cam_angle_32, Zooms_32, dwtmp, m_ptzPosCurrent);
			}
			else{
    			contral_cam(lUserID_32, 180 + standard_cam_Pans_32, 180 - result_cam_angle_32, Zooms_32, dwtmp, m_ptzPosCurrent);
			}
		}

	}

}

int main()
{
    //初始化全局变量
    //memset(arrConSocket,0,sizeof(struct MySocketInfo)*10);
 
    printf("开始socket\n");
    /* 创建TCP连接的Socket套接字 */
    int socketListen = socket(AF_INET, SOCK_STREAM, 0);
    if(socketListen < 0){
        printf("创建TCP套接字失败\n");
        exit(-1);
    }else{
        printf("创建套接字成功\n");
    }
    /* 填充服务器端口地址信息,以便下面使用此地址和端口监听 */
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY); /* 这里地址使用全0,即所有 */
    server_addr.sin_port=htons(2000);
    if(bind(socketListen, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) != 0){
        perror("绑定ip地址、端口号失败\n");
        exit(-1);
    }else{
        printf("绑定ip地址,端口号\n");
    }
    /* 开始监听相应的端口 */
    if(listen(socketListen, 10) != 0){
        printf("开启监听失败\n");
        exit(-1);
    }else{
        printf("开启监听成功\n");
    }
    /* 接受连接套接字 */
    pthread_t thrAccept;
    pthread_create(&thrAccept,NULL,fun_thrAcceptHandler,&socketListen);
    std::thread tw(gets_angle);
    
 
    /* 实时发送数据 */
    while(1){
        //判断线程存活多少
        int i;
        for(i=0;i<thrReceiveClientCount;i++){
            if(checkThrIsKill(arrThrReceiveClient[i]) == 1){
                printf("有个线程被杀了\n");
                thrReceiveClientCount--;
            }
        }
        printf("当前有接受数据线程多少个:%d\n",thrReceiveClientCount);
 
        // 可以录入用户操作选项,并进行相应操作
        char userStr[30] = {'0'};
        scanf("%s",userStr);
        if(strcmp(userStr,"q") == 0){
            printf("用户选择退出!\n");
            break;
        }
        // 发送消息
        if(conClientCount <= 0){
            printf("没有客户端连接\n");
        }else{
            int i;
            for(i=0; i<conClientCount; i++){
                //int sendMsg_len = send(arrConSocket[i].socketCon, userStr, 30, 0);
				std::cout << "arrConSocket[i].socketCon" << arrConSocket[i].socketCon << std::endl;
                int sendMsg_len = write(arrConSocket[i].socketCon,userStr,30);
                if(sendMsg_len > 0){
                    printf("向%s:%d发送成功\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
					std::cout << "arrConSocket[i].ipaddr" << arrConSocket[i].ipaddr << std::endl;
					std::cout << "arrConSocket[i].port" << arrConSocket[i].port << std::endl;
                }else{
                    printf("向%s:%d发送失败\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
                }
            }
        }
 
        sleep(0.5);
    }
 
    // 等待子进程退出
    printf("等待子线程退出,即将退出!\n");
    //char *message;
	void * a;
    pthread_join(thrAccept,&a);
    tw.join();
    return 0;
}



 上述代码中gets_angle()函数是获取客户端所需要的信息

通过设定全局变量

float result_cam_angle_31;
float result_cam_angle_32;

创建新的线程

std::thread tw(gets_angle);
tw.join();

来实时获取客户端所需要的信息。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值