C++项目代码出现问题汇总

1、UDP多个通信对象时,端口号绑定与端口号监听问题
 if (bind((this->sockfds)[i], (sockaddr*)&(this->serverAddr), sizeof((this->serverAddr))) == SOCKET_ERROR) {
     std::cerr << "Bind failed" << std::endl;
     closesocket((this->sockfds)[i]);
     WSACleanup();
     return -1;
 }

int n = recvfrom((sthis->sockfds)[i], buffer, 1024, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
if (n == SOCKET_ERROR) {
    std::cerr << "recvfrom failed" <<i++<< std::endl;
    continue;
}

其中bind函数可以将serverAddr中的端口号绑定到sockfds数组中,而在resvfrom函数可以监听sockfds[i]对应套接字的端口号信息,当有数据发到该端口号时,recvfrom函数可以接收到该消息。

2、多线程绑定函数问题
  void UdpCommunication::udp_receive(int i) {
    // 设置服务器地址结构
    struct sockaddr_in clientAddr;
    memset(&clientAddr, 0, sizeof(clientAddr));
    char buffer[1024];
    while (true) {
        int clientAddrLen = sizeof(clientAddr);
        //cout << "brfore recv:" << i << endl;
        //监听编号为i的端口号,消息没发过来的时候处于阻塞状态
        int n = recvfrom((sthis->sockfds)[i], buffer, 1024, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        if (n == SOCKET_ERROR) {
            std::cerr << "recvfrom failed" <<i++<< std::endl;
            continue;
        }
        // 获取发送方的 IP 地址和端口号
        char ip[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &clientAddr.sin_addr, ip, INET_ADDRSTRLEN);
        int remotePort = ntohs(clientAddr.sin_port);  //发送端端口号
        buffer[n] = '\0';
        cout << "getdata:" << buffer << ":" << remotePort << ":" << ip << endl;

        //接收到消息后,需将消息发送到消息队列中
    }

}
//创建多个线程分别监听对应端口号数量的消息,每个线程需都需调用udp_receive(int i)函数
void UdpCommunication::udp_receives() {
    //根据开放的端口数量,创建数据接收线程,每个端口号开放一个监听线程
    for (int i = 0; i < ipInfo.size(); i++) {
        thread newThread(udp_receive, i);
        //使用detach运行线程,不会阻塞其他线程,各线程根据系统分配获取时间片
        newThread.detach();    
    }
}

使用newThread创建线程时,因为udp_receive函数为类的成员函数,但创建时newThread无法绑定类的普通成员函数,对于类内的函数,newThread只能绑定类的静态成员函数,因此udp_receive函数只能用static修饰。

因为udp_receive为静态成员函数,所以只能访问类的静态成员变量,如果该函数内要使用类的普通成员函数,可以将该类初始化一个静态指针。

	static UdpCommunication *sthis;

在类的构造函数中,可以将该静态指针指向当前对象。

//类的静态成员变量在.h文件中声明,如果要在cpp文件中使用,要在cpp文件中链接
UdpCommunication* UdpCommunication::sthis;   

UdpCommunication::UdpCommunication(vector<IPInfo> info) {
    sthis = this;  //将当前对象指令静态当前对象
}

这样在静态成员函数中即可使用类的普通成员变量。

int n = recvfrom((sthis->sockfds)[i], buffer, 1024, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);

3、VS2022使用gitee推送最新代码

在按照网上的方法创建了gitee仓库,使用vs2022git功能连接远程仓库后,在推送了第一次程序后如果后面程序还需要更新,前提是先从仓库克隆上一次提交的程序,在克隆的程序基础上进行修改,修改后,需要提交时,可点击vs2022界面右下角的git更改。

随后更改数的地方会出现跟上次推送相比,程序发生了改变的文件。

随后在输入框内输入本次提交的描述,点击提交选项小箭头,选择全部提交并推送即可

4、类模版不能定义在.h文件,实现在.cpp文件

像:

这样会报错,同一个函数使用模版必须只在.h文件或者.cpp文件定义和实现

5、VS2022读取XML文件内中文乱码问题

解决方法:

在编码的地方设置编码格式为简体中文

此时XML文件的编码格式也会自动发生变化

这个时候中文将不会乱码

6、C++使用map的find函数获取map<key,value>中的value

map中的find函数返回的是一个key对应值的迭代器位置,即返回的是一个:

map<string, vector<Fault>>::iterator it = faultsMap.find(u.systemName);

要想获取该key对应的value值,只需获取该迭代器的second即可:

(*it).second;

这里获取的就是key为 u.systemName 时对应的 vector<Fault>

7、C++父类对象调用子类的函数问题

在父类定义函数时,如果采用该方法定义messageCopy函数

class ObjectInterface {
public:
	int faultID;
	string systemName;
	
	void messageCopy(char* s, int length);

}

子类的实现:

class UWMU:public ObjectInterface{
public:
	//接收报文
	unsigned short A;
	unsigned short B;

	void messageCopy(char *s, int length) {   //将报文拷贝到指定地方
		memcpy(&(this->A), s, length);
		cout <<"this.A" << this->A << endl;
		cout << "this.C" << this->C << endl;
	}
}

 使用父类的接口调用子类的函数,其中getSysObj会返回UWMU对象:

ObjectInterface *obj = getSysObj(remotePort);   //根据远程端口区分不同的系统
obj->messageCopy(buffer, n);


------------------------------------------------------------------------------
#include "Global.h"
#include <string>

UWMU *uwmu=new UWMU;


ObjectInterface* getSysObj(int port) {
	switch (port)
	{
	case 2005:
		return uwmu;
	default:
		return NULL;
		break;
	}
}
--------------------------------------------------------------------------------

 在使用上述方法调用memageCopy函数后,编译报错,无法解析的外部符号:

解决方法:在父类函数定义是使该函数定义为虚函数且使用{}使该函数的定义更完整。

class ObjectInterface {
public:
	int faultID;
	string systemName;
	
	virtual void messageCopy(char* s, int length) {  }   //注意这里函数的定义要加{} ,如果用;结尾会报错
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值