多次测试发现收发不稳定,经常卡死。
将输入的ip地址打印出来,发现很多时候按键按快了会输入不了,于是连接了错误的ip地址导致程序无响应,所以根本原因是GetIP函数不稳定。
对GetIP()做了些调整,使输入实时显示出来,另外降低了Sleep的时间,这样就无大碍了。另外加入了退格键修改的功能,其间需要做到刷新屏幕的一小部分,像d3ddev.clear函数各参数详细功能这样的问题,可以去查一篇叫《directx9.0 入门手册》的文章。
(2014.3.27注: msdn当然更好)
先试着用阻塞模式做了一些远程控制,虽然能达到一定效果,不过明显仅靠阻塞模式是完全行不通的,只要一方不做任何动作,另一方就将永远卡在recv()中。要么采用多线程,要么用非阻塞。我说过不想在学一样东西的同时又掺杂进另一样,所以还是继续研究非阻塞。
重看了遍《windows网络编程》第五章,主要讲各种模型,说下我的初步理解。“模型”这个词的原文是“method”,也就是“方法”。并非如我之前所理解的网络编程主要分两种模式,然后非阻塞模式下再分几种模型,实际上阻塞模式也可以称为一种方法,只不过不太好用。单纯的设置为非阻塞模式,处理起来并不方便,所以微软又为我们提供了很多更好用的函数,称作“方法”。这些方法各有利弊,具体的细节我就不多介绍了,以免误导大众。不同的人会有不同的偏好,比如一个叫彭博的人写的《游戏编程指南》用的是WSAAsyncSelect( )。作为初学者我还是选用看起来比较简单的那种,就是select。《PC游戏编程网络篇》介绍的也是这种方法。
常识:
在定义全局变量后马上跟一句变量赋值语句会导致编译错误。正确的做法是定义同时就赋初值,或者等到代码段再赋值。简单的说在函数体外写单独的语句是个很2b的行为。
select函数不难用,很快写好了自己的收发函数。
暂时假设网络延迟永远理想,即收发延时都低于30ms的情况(延时过高或不稳定情况下问题会变得复杂,这个后面再说)。
常识:
定义一个结构体
Struct cmd
{
Int a;
Int b;
}
如何在send(char *)中发送呢?
只需要将结构体的指针强制转换就行了,如send((char*)&cmd)。
(2013.8.12注:这里的用法会不会导致send越界有待商榷,需进一步斟酌)
(2014.3.27注:很明显send函数参数列表中应包含size,此处极有可能产生bug)
常识:
快速将一整段内存置为某一值用memset()很方便,这样就不用自己费力写一些结构体清零之类的函数了。
功能写好后,测试现象很奇怪,只有踢腿能在远程反映出来,而且延迟极大。将单次循环的周期调长,仍旧是同样现象,证明和延时无关。
最终发现是由于select_send函数中发送字节的长度写错…修正后就一切正常了。