遇到的问题集合(倒序)

7.Qt跨线程访问对象以及QMainWindow的父对象

有两个问题
	第一个问题是在qt里,两个继承自QMainWindow的窗口类A和B,有对象A1、B1当我试图在A1的构造函数里:
	B1 = new B1(this);
	在B的构造函数里,可以通过参数parent取得A1对象,
	但是当我尝试在B1的另一个成员函数里使用parent()成员函数取得父对象时,其返回值总是空指针
	也许是QMainWindow对象不应该有父对象?查了查也没找到
	查看QMainWindow的定义,也没看到复写parent成员函数,另一个parentwidget函数也只是调用parent而已。
	最后不得不在B类里添加一个成员指针,指向A类的对象。

	第二个问题是跨线程访问QT对象的
	需求:在一个异步线程里,从网络上拉取好友列表,然后创建QListWidgetItem条目,把这些条目添加到QListWidget中
		  同时更新ui的进度条
	陷入两难境地:
		如果同步执行:那么该窗口的show调用会被阻塞,直到把这些条目都添加进去,并且更新进度条之后才会显示窗口,
					  也就是说看不见进度条的更新了
		如果异步执行:输出窗口里会显示Cannot set parent, new parent is in a different thread之类的报错,
					  大意就是不在同一个线程操作是禁止的
	解决方法参考自:https://blog.csdn.net/u012321968/article/details/108214644
		invokeMethod这个方法,会把第二参数的函数,放到第一参数对象所在的线程执行
		整个函数还是异步执行的,只不过在这个函数里跨线程操作对象的部分,使用invokeMethod包裹了起来
		for (auto it : MdFriendList)
		{				
			QMetaObject::invokeMethod
			(
				ui.listWidget,
				[=]()
				{
					QListWidgetItem* Item = new QListWidgetItem();
					FriendItemClass* widget = new FriendItemClass();
					widget->ui.label->setText(it.second.c_str());
					widget->ui.label_2->setText(QString::fromLocal8Bit(" 离线"));
					Item->setSizeHint(widget->minimumSizeHint());
					ui.listWidget->addItem(Item);
					ui.listWidget->setItemWidget(Item, widget);
				}
			);
		}

6.QString 到 char * 中文复制的一个问题

问题出现:从qt控件获取输入的一个中文字符串,然后使用strncpy复制到char * 的问题,当字符串没有中文就不会出现,有中文就出现

原来有问题的代码
		char dst[100];
		int size = ui.lineEdit_4->text().toLocal8Bit().length();
		strncpy(dst, ui.lineEdit_4->text().toStdString().c_str(), msg.size );
		测试:
			控件ui.lineEdit_4输入四个汉字,size为8(打印出来验证过),strncpy后,再打印dst,就会出现乱码
		一开始以为编码问题,尝试过ui.lineEdit_4->text().toUtf8()    ui.lineEdit_4->text().toLatin1()
		以及其他各个和字符集相关的text()成员函数,总是有乱码
		但是直接打印ui.lineEdit_4->text().toStdString().c_str()就没有问题

		尝试打印ui.lineEdit_4->text().toStdString().length();
		同样四个汉字
		ui.lineEdit_4->text().toLocal8Bit().length();  的值是8
		ui.lineEdit_4->text().toStdString().length();  的值是12
		多次验证后,确实如此
		直接打QT印控件的字节数一个汉字2字节,转成std::string后每个汉字占了3字节
		
没有问题的代码
		char dst[100];
		int size = ui.lineEdit_4->text().toStdString().length();
		strncpy(dst, ui.lineEdit_4->text().toStdString().c_str(), size);

5.信号处理的一个问题

  在link.的对SIGPIPE信号的处理是危险的,详见本问题最后的截图,该截图来自我的另一篇文章
    关于信号的处理内容见第二张图,第一张图中被注释掉的是原来的代码。
    关于SIGPIPE的处理,一开始是替换处理过程,后来又改成SIG_IGN,但是SIG_IGN到底算不算一个《信号处理程序》不得而知,也懒得去测了,而且当下这个情况,对SIGPIPE也没有处理的必要,最后就改成了直接阻塞掉它。
在这里插入图片描述
在这里插入图片描述

4.(已解决)非阻塞套接字遇到的一个问题

  一开始想使用非阻塞套接字来进行传输,通过unp第16章描述,如下:在这里插入图片描述
  主要问题是:
    对于recv,在接收缓冲区没有数据时,EWOULBLOCK错误
    对于send,在发送缓冲区满时,EWOULBLOCK错误
    书中描述的语义大概是recv和send的返回EWOULBLOCK,导致我一度使用EWOULBLOCK == recv(sock, buf, 1, 0)来判断,但实际上是recv和send返回-1,而后通过errno来判断:

if( 0 >= recv(sock, buf, 1, 0)
	if(EWOULBLOCK  == errno)
		...

  问题发现过程:在接收端打印recv返回值时,出现了有时返回-1,但是连接并未断开,随后有继续收到数据的情况,通过将errno转换为错误信息后得到:Resource temporarily unavailable。之后在链接.中找到答案:在这里插入图片描述  该链接中的描述解决书中的误导。

  另外,在最后的测试中,recv在接收缓冲区空的情况下成功判定到了EWOULBLOCK,但是在send发送缓冲区塞满的情况下,send返回了-1值,errno值却是0
                                      2020年9月19日19:17

  今天早上突然想起来,recv是在linux测得,send是在win上测的,怪不得结果不一样,经过刚刚验证后,互换平台代码,得出最终结论:
    linux平台:非阻塞套接字,send在发送缓冲区满 和 recv在接收缓冲区空时,返回-1,errno被设置为EWOULBLOCK(11)
    win平台:非阻塞套接字,send在发送缓冲区满 和 recv在接收缓冲区空时,返回-1,errno值为0

                                      2020年9月20日07:27

3.(已解决)使用pcap发送arp遇到的一个字节对齐问题

  刚才使用pcap发送一个arp包,用wireshark抓包,抓的包和预期对不上。
  其中源MAC IP、目的MAC IP,只有源MAC是正确的,确信填写的代码没有出错。
  目的MAC填全0,但是抓到的包是01-07-00-00-00-00。后来阴差阳错试着把源mac也填到目的mac上试试是个什么情况,抓到如下包:在这里插入图片描述
  情况已然有些明了,从源IP字段开始,所有数据之前都被偏移了两个字节。比如源IP地址那里,源IP应该是192.168.1.7,但是1.7却偏移到了目的MAC的位置,而目的mac地址也依次偏移了两个字节。
  开始检查定义ARP包的结构:
    首先确定了IN_ADDR结构是4字节:在这里插入图片描述
    接下来查看整个结构,如以下图1,结构各个成员加起来应该是28字节,但是sizeof出来却是32字节(2+2+1+1+2+6+4+6+4)。在这里插入图片描述
    接着我删掉了,源IP和目标IP字段,如图2,这时sizeof之后只有20字节,之前已经确认过IN_ADDR是4字节,删掉了两个IN_ADDR结构却减少了12字节,此时已经确定是字节对齐的问题了:在这里插入图片描述
    最后,通过调整成员顺序(图三)或者合并字段(图四),解决字节对齐,sizeof的结构长度已经是28字节(一个arp包长度)了,之后发送的ARP请求包,也在wireshark中抓到了回复包: 在这里插入图片描述
在这里插入图片描述
                                      2020年8月19日15:16

2.(未解决)远程调试Linux,找不到libnss_dns.so.2和libresolv.so.2

  今天看完unp第11章,想着测试一下gethostbyname和getservbyname,但是远程调试(云服务器)的时候,只要一进入这两个函数,就会断点,然后报如下错,找不到libnss_dns.so.2和libresolv.so.2。接着我把这份代码放到本地的一个虚拟机上跑,可执行文件生成了,但是执行的时候,提示大概也是找不到库之类的,也没找到安装他们的方法。截图:在这里插入图片描述

                                      2020年7月19日23:02:11

1.第一条太菜了删掉了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值