我需要用一种传统的网络接口NetBIOS编写两台计算机通信的程序,我的发送部分基本没有什么问题,可接收出现了不少的问题:
第一个问题:程序接收数据时,只能正确接收一次。第二次发送不同的数据时,接收文本框没有任何变化。
第二个问题:在对话框中再任意添加一个文本框,通过向导给这个文本框添加一个值变量(CString类型),其他地方不给这个变量赋任何值,但当程序第一次运行时这个文本框也能显示发送的数据。
请各位高手看看,到底是怎么会事?现将主要代码贴出来:
==============相关变量类型和结构定义========
struct ZFS {char text[20];};
struct ZFS Buffer;//[50]; //缓冲
int p_Buffer_In,p_Buffer_Out; //缓冲指针
CString ReceiveBuffer;
==============发送数据函数==================
bool CNetBios::Send(CString callname,CString *SendData,int len)
{
bool result=false;
if(ncbnum)
{
ZeroMemory(&ncb,sizeof(NCB));
//memset((char*)&ncb,0,sizeof(NCB));
ncb.ncb_command=NCBDGSEND; //同步数据报发送
ncb.ncb_num=ncbnum;
ncb.ncb_buffer=(unsigned char*)(LPCTSTR)SendData;
ncb.ncb_length=len;
memcpy(ncb.ncb_callname,callname,strlen(callname));
ncb.ncb_lana_num=uselana;
if(Netbios(&ncb)==NRC_GOODRET)
{
result=true;
}
}
return result;
}
===============发送按钮函数==================
void CCNetBiosDlg::OnSendButton5()
{ UpdateData(TRUE);
if(SendBios.Send(m_starget,m_stext,sizeof(ZFS))==true)
{
m_slabel="数据已经发出";
}
else
m_slabel="发送有误";
UpdateData(FALSE);
}
====================接收函数====================
bool CNetBios::Receive(void (CALLBACK *ncb_post)(NCB *))
{
bool result=false;
if(ncbnum)
{
memset(&ncb,0,sizeof(NCB));
ncb.ncb_command=NCBDGRECV|ASYNCH;//异步接收
ncb.ncb_num=ncbnum;//
ncb.ncb_buffer=(unsigned char*)(LPCTSTR)ReceiveBuffer;
//CString ReceiveBuffer;
ncb.ncb_length=50; //类中设置的接收缓冲区的大小
ncb.ncb_post=ncb_post;
ncb.ncb_lana_num=uselana;
if(Netbios(&ncb)==NRC_GOODRET)
result=true;
}
return result;
}
这里用了个回调函数,这个回调函数是:
CCNetBiosDlg *BiosDlg;//因为RecPostProgram(pn)是对话框类的成员函数,所以//就声明了这个全局变量
void __stdcall Post(NCB * pn) //POST例程
{
BiosDlg->RecPostProgram(pn);//调用CCNetBiosDlg对象中的处理函数
}
================RecPostProgram(pn)======================
void CCNetBiosDlg::RecPostProgram(NCB *ncb)
{
struct ZFS *recdata;
if(ncb->ncb_length==sizeof(ZFS))
{
recdata=(struct ZFS *)ncb->ncb_buffer; //将接收缓冲区指针转为结构指针
Buffer[p_Buffer_In]=*recdata;//将数据复制至缓冲
p_Buffer_In++; //接收缓冲指针移动
if(p_Buffer_In==50)
p_Buffer_In=0;
}
PostMessage(WM_MESSAGE,0,0); //产生一个消息
RecBios.Receive(&Post); //继续接收过程,首次调用Receive(&Post)
//函数是在NetBIOS成功注册返回以后。
}
============自定义消息函数===================
void __fastcall CCNetBiosDlg::UseMessage(UINT uMsg)
{
while(p_Buffer_In!=p_Buffer_Out) //如有新的数据则执行如下程序
{
m_sreceive=Buffer[p_Buffer_Out].text;//m_sreceive是用来接收显示数据
//的文本框变量
p_Buffer_Out++; //读取缓冲指针移动
if(p_Buffer_Out==50)
p_Buffer_Out=0;
}
}
这个程序是参考一个用C++ Build6开发且能正确运行的程序改写到VC6的。改写过程中很不顺利,开始根本不能接收数据,后来通过试的方法发现是有些参数类型不对,如ncb.ncb_buffer=(unsigned char*)(LPCTSTR)ReceiveBuffer;不能写成ncb.ncb_buffer=(unsigned char*)ReceiveBuffer;或ncb.ncb_buffer=ReceiveBuffer;再如:CString ReceiveBuffer;不能该为char ReceiveBuffer [50];否则程序就第一次运行都不能接收到数据。
还有,单步调试时程序运行到回调函数的recdata=(struct ZFS *)ncb->ncb_buffer;这句就不向下运行,自定义消息根本没有运行,真是奇怪及了!!
第一个问题:程序接收数据时,只能正确接收一次。第二次发送不同的数据时,接收文本框没有任何变化。
第二个问题:在对话框中再任意添加一个文本框,通过向导给这个文本框添加一个值变量(CString类型),其他地方不给这个变量赋任何值,但当程序第一次运行时这个文本框也能显示发送的数据。
请各位高手看看,到底是怎么会事?现将主要代码贴出来:
==============相关变量类型和结构定义========
struct ZFS {char text[20];};
struct ZFS Buffer;//[50]; //缓冲
int p_Buffer_In,p_Buffer_Out; //缓冲指针
CString ReceiveBuffer;
==============发送数据函数==================
bool CNetBios::Send(CString callname,CString *SendData,int len)
{
bool result=false;
if(ncbnum)
{
ZeroMemory(&ncb,sizeof(NCB));
//memset((char*)&ncb,0,sizeof(NCB));
ncb.ncb_command=NCBDGSEND; //同步数据报发送
ncb.ncb_num=ncbnum;
ncb.ncb_buffer=(unsigned char*)(LPCTSTR)SendData;
ncb.ncb_length=len;
memcpy(ncb.ncb_callname,callname,strlen(callname));
ncb.ncb_lana_num=uselana;
if(Netbios(&ncb)==NRC_GOODRET)
{
result=true;
}
}
return result;
}
===============发送按钮函数==================
void CCNetBiosDlg::OnSendButton5()
{ UpdateData(TRUE);
if(SendBios.Send(m_starget,m_stext,sizeof(ZFS))==true)
{
m_slabel="数据已经发出";
}
else
m_slabel="发送有误";
UpdateData(FALSE);
}
====================接收函数====================
bool CNetBios::Receive(void (CALLBACK *ncb_post)(NCB *))
{
bool result=false;
if(ncbnum)
{
memset(&ncb,0,sizeof(NCB));
ncb.ncb_command=NCBDGRECV|ASYNCH;//异步接收
ncb.ncb_num=ncbnum;//
ncb.ncb_buffer=(unsigned char*)(LPCTSTR)ReceiveBuffer;
//CString ReceiveBuffer;
ncb.ncb_length=50; //类中设置的接收缓冲区的大小
ncb.ncb_post=ncb_post;
ncb.ncb_lana_num=uselana;
if(Netbios(&ncb)==NRC_GOODRET)
result=true;
}
return result;
}
这里用了个回调函数,这个回调函数是:
CCNetBiosDlg *BiosDlg;//因为RecPostProgram(pn)是对话框类的成员函数,所以//就声明了这个全局变量
void __stdcall Post(NCB * pn) //POST例程
{
BiosDlg->RecPostProgram(pn);//调用CCNetBiosDlg对象中的处理函数
}
================RecPostProgram(pn)======================
void CCNetBiosDlg::RecPostProgram(NCB *ncb)
{
struct ZFS *recdata;
if(ncb->ncb_length==sizeof(ZFS))
{
recdata=(struct ZFS *)ncb->ncb_buffer; //将接收缓冲区指针转为结构指针
Buffer[p_Buffer_In]=*recdata;//将数据复制至缓冲
p_Buffer_In++; //接收缓冲指针移动
if(p_Buffer_In==50)
p_Buffer_In=0;
}
PostMessage(WM_MESSAGE,0,0); //产生一个消息
RecBios.Receive(&Post); //继续接收过程,首次调用Receive(&Post)
//函数是在NetBIOS成功注册返回以后。
}
============自定义消息函数===================
void __fastcall CCNetBiosDlg::UseMessage(UINT uMsg)
{
while(p_Buffer_In!=p_Buffer_Out) //如有新的数据则执行如下程序
{
m_sreceive=Buffer[p_Buffer_Out].text;//m_sreceive是用来接收显示数据
//的文本框变量
p_Buffer_Out++; //读取缓冲指针移动
if(p_Buffer_Out==50)
p_Buffer_Out=0;
}
}
这个程序是参考一个用C++ Build6开发且能正确运行的程序改写到VC6的。改写过程中很不顺利,开始根本不能接收数据,后来通过试的方法发现是有些参数类型不对,如ncb.ncb_buffer=(unsigned char*)(LPCTSTR)ReceiveBuffer;不能写成ncb.ncb_buffer=(unsigned char*)ReceiveBuffer;或ncb.ncb_buffer=ReceiveBuffer;再如:CString ReceiveBuffer;不能该为char ReceiveBuffer [50];否则程序就第一次运行都不能接收到数据。
还有,单步调试时程序运行到回调函数的recdata=(struct ZFS *)ncb->ncb_buffer;这句就不向下运行,自定义消息根本没有运行,真是奇怪及了!!
解决方案 »
- Win7权限问题
- Access货币字段,已读至RecordSet中,_variant_t变量,我现需将它按转为CString,并保留货币符号及千位号,如何实现?CString.Format是否可以?
- 怎么用MDI程序中的Serialize写文件?发现很奇怪的现象!
- 帮忙看个win32程序:
- 关于类似图层的解决方法(欢迎讨论,参与就有分)
- 请教日期问题
- 一个简单的问题
- 我这里有一些BIOS的代码 谁想要
- 如何使用 cspinbuttonctrl?
- 代码如何实现“显示器亮度调节”
- 如何得到指定文件的公司名称,文件描述,内部名称,合法版权,原始文件名,产品名称,产品版本等一系列信息?
- 基于位的搜索,求高效算法
如果是这样,你只需在Receive中new一块堆内存来接收数据,然后由RecPostProgram()函数负责使用完ncb->ncb_buffer指针后释放它。
要怎么写代码?能否给一个参考?