一,远程遥控opengl模型功能说明
在QT按钮socket远程控制opengl模型我的学习笔记后,即local调试后,将VS工程修改到linux中编译通过今天调试。
实现功能说明
- server端在ubuntu18.04上。启动opengl模型,读取client发来的控制命令,作为摄像头的运动命令,来显示模型。心跳包由server端每隔1s发出。
- client端在win10上。QT按钮更新后发送命令。命令包括上/下/左/右/停止。并且每隔5s监控心跳情况,若断线则重连。
二,遇到的编译调试问题
- 编译出错
example1.c:1: error: stray ‘\357’ in program
解决:把文件放到windows系统中,用“记事本”打开这些文件,然后“另存为”,编码选为ASNI,然后再到linux底下重新用编译器编译,一般都能通过了!
2.编译出错
invalid use of incomplete type struct 或者是class的解决办法
解决:出现这个问题,表明编译器不知道所用的struct 或者是class的具体实现,通常出现在如下情况:假设我们有一个class some定义在some.h中,实现在some.cpp中,我们在other.cpp中要用到这个some 的方法,于是我们再other.h中声明可一个class some,并声明了要用到的方法,这样就会导致上述的问题,解决这个问题的方法是:在other.cpp中include some.h,这样编译器就会根据该头文件找到class some的具体定义,问题也就解决了。
3.ubuntu能ping通,但是不能连接socket
ubuntu通过界面设置,设置静态IP地址后通过安装telnet服务器,win10安装telnet客户端,其默认端口为23,关闭防火墙后,win10能远程访问ubuntu。ubuntu端通过netstat -a|grep tcp能查看到连接状态。但是我的还是连接不上,后来查到原因是htons传入的参数int型的1234,结果不正确。把htons(aPort);改成htons(1234);后连接成功。
- 心跳包不是每隔1s发送
原因是ubuntu下我还是用Sleep(1000),结果变成1000s了,在linux下1s只要传参数Sleep(1)
- 最严重的问题是
断线后,服务器的接收一直阻塞等待数据,而客户端已经重连成功,心跳接收也成功。导致看上去客户端发了上/下/左/右的控制指令,服务器模型不受控。
解决方法:
由于server端一个线程用于接收,一个线程用于发送。而拔线后server端的recv依然阻塞,无法识别,所以将recv参考我之前的blog,改成select模型。带timeout 3s。之前blog模型这样处理后就没问题,因为有交互,先send后recv,而且一定是连续发送给server端的。而我本次的client检测到key命令变换才发给server端,所以会出现client key不变的时候,server select模型检测到自动断线。所以我将client也改了下,每隔2s发一帧保活指令,目的是让select不要在3s内超时。不管客户端异常退出,还是拔线后,都可以重连成功。线程对象交互模型如下,增加了红色方块处理。
其实这样的修改也并不好,因为客户端每隔2s发报文给服务端,增加了网络负担。后来网上搜索到了另外一种处理方法。将来再做小项目可以考虑修改为如下交互模型。
服务器检测,当检测到某个客户端在n秒内,没有发送数据了,就给该客户端发个心跳包,等待客户端回复。
客户端回复超时,那服务器就可以判断这个客户端断了,服务器关闭这个socket。网狐棋牌就这么搞的 。