Welcome

首页 / 软件开发 / C++ / 标准MFC WinSock ActiveX控件开发实例(II)高级篇

标准MFC WinSock ActiveX控件开发实例(II)高级篇2011-02-07 vckbase 小辉回顾:在上一篇文章《标准MFC WinSock ActiveX控件开发实例》中我们详细介绍了控件的开发过程,以及接口和事件的

添加和响应方法。现在我们将继续上次没有写完的控件继续进行开发,并完善作为一个WinSock控件应该具备的功能。

二、按照前一篇文章提到的知识,现在我们来添加两个新的接口分别是SendData()和GetData(),它们看起来如下:

//网络数据发送,在指定的超时时间内进行发送然后返回,成功返回实际发送字节数,否则返回负数
long CMFCWinSockCtrl::SendData(const VARIANT FAR& Data,

const VARIANT FAR& DataType,

const VARIANT FAR& DataLength,

const VARIANT FAR& TimeOut)
{

// TODO: Add your dispatch handler code here

return 0;
}

//获取数据,并指定获取数据的超时时间,返回实际获取到的数据长度,否则返回负数
long CMFCWinSockCtrl::GetData(VARIANT FAR* Data,

const VARIANT FAR& DataType,

const VARIANT FAR& DataMaxLength,

const VARIANT FAR& TimeOut)
{

// TODO: Add your dispatch handler code here

return 0;
}

两个接口的参数除了第一个参数外,其它都类似。SendData()是发送数据,不要求将数据带回,因此直接用 VARIANT,而GetData()则要求将数据带回来给调用者,因此定义为 VARIANT *类型,第二个参数DataType故名思义是定义所传送或接收数据的类型,第三个参数是传送或接收数据的长度,这里的长度以char作为一个长度,假如传入的类型是int类型,则长度为4,如果定义的是字符串,一个中文字符占用2个长度。最后一个参数,是网络发送或读取时的超时时间。

三、为Connect()接口添加源代码,看起来如下:

//网络数据发送,在指定的超时时间内进行发送然后返回,成功返回实际发送字节数,否则返回负数
long CMFCWinSockCtrl::SendData(const VARIANT FAR& Data,

const VARIANT FAR& DataType,

const VARIANT FAR& DataLength,

const VARIANT FAR& TimeOut)
{

// TODO: Add your dispatch handler code here

if(!OnlySock)

return -1;//网络尚未开始建立连接

int gDataType = VariantToLong(DataType);

long gDataLength = VariantToLong(DataLength);

int gTimeOut = VariantToLong(TimeOut);

if(gDataType < 0)

return -2;

if(gDataLength <= 0)

return -2;

if(gTimeOut < 0)

return -2;

switch(gDataType)

{

case 0://默认形式,这时如果发现Data为整型数组,将不进行任何转换,直接把一个int传给一个char传送(数据可能溢出范围)

case 1://当指定该值为1时,当Date为长整型数组时,将把一个long转换成四个char传送

case 2://当指定该值为2时,当Date为整型数组时,将把一个int转换成四个char传送

case 3://当指定该值为3时,当Date为无符号短整型数组时,将把一个unsigned short转换成两个char传送

case 4://当指定该值为4时,当Date为BYTE数组时,将把一个BYTE转换成一个char传送

case 5://当指定该值为5时,当Date为短整型数组时,将把一个short转换成两个char传送

case 6://当指定该值为6时,当Date为浮点型数组时,将把一个float转换成四个char传送

case 7://当指定该值为7时,当Date为双精度数组时,将把一个double转换成八个char传送

break;

default://如果不在上面取值范围内,将按当前的Data相应类型进行传送

break;

}

timeval tv;

fd_set fdwrite;

int len = 0;

long m = 0;

long n = 0;

long changetype = 0;//将浮点型数据进行类型转换,再进行传送

VARIANT gData;

VariantInit(&gData);

//送出信息至服务器

FD_ZERO(&fdwrite);

tv.tv_sec = gTimeOut;//指定时间后返回

tv.tv_usec = 0;

FD_SET(OnlySock,&fdwrite);//是否可以发送数据

select(0,NULL,&fdwrite,NULL,&tv);

char *buffer = NULL;

if(FD_ISSET(OnlySock,&fdwrite))

{

switch(Data.vt)

{

case VT_BSTR://按字符串形式发送

buffer = _com_util::ConvertBSTRToString(Data.bstrVal);

break;

case VT_BYREF|VT_UI1:
//按BYTE*形式发送

buffer = new char[gDataLength];

memcpy(buffer,Data.pbVal,gDataLength);

break;

case VT_BYREF|VT_I1://按 char * 发送

buffer = new char[gDataLength];

memcpy(buffer,Data.pcVal,gDataLength);

break;

case VT_ARRAY|VT_I4://以长整型数组发送

gData.vt = VT_I4;

if(gDataType!=0)//long = char*4

{

//sizeof(long),在这里一个长整型的长度为4个char

buffer = new char[gDataLength];

for(m=0,n=0; n<gDataLength/4; n++)

{


SafeArrayGetElement(Data.parray,&n,&gData.lVal);


buffer[m++] = (gData.lVal>>24)&0xff;


buffer[m++] = (gData.lVal>>16)&0xff;


buffer[m++] = (gData.lVal>>8)&0xff;


buffer[m++] = gData.lVal&0xff;

}

}

else//long = char*1 //数据可能溢出

{

buffer = new char[gDataLength];

for(m=0,n=0; n<gDataLength; n++)

{


SafeArrayGetElement(Data.parray,&n,&gData.lVal);


buffer[n] = (char)gData.lVal;

}

}

break;

case VT_ARRAY|VT_INT://以整型数组发送

gData.vt = VT_INT;

if(gDataType != 0)

{

//一个int等于四个char

buffer = new char[gDataLength];

for(m=0,n=0; n<gDataLength/4; n++)

{


SafeArrayGetElement(Data.parray,&n,&gData.intVal);


buffer[m++] = (gData.intVal>>24)&0xff;


buffer[m++] = (gData.intVal>>16)&0xff;


buffer[m++] = (gData.intVal>>8)&0xff;


buffer[m++] = gData.intVal&0xff;

}

}

else

{

buffer = new char[gDataLength];

for(n=0; n<gDataLength; n++)

{


SafeArrayGetElement(Data.parray,&n,&gData.intVal);


buffer[n] = (char)gData.intVal;

}

}

break;

case VT_ARRAY|VT_UI1://以BYTE数组发送

gData.vt = VT_UI1;//一个char等于一个BYTE不必进行转换

buffer = new char[gDataLength];

for(n=0; n<gDataLength; n++)

{

SafeArrayGetElement(Data.parray,&n,&gData.bVal);

buffer[n] = gData.bVal;

}

break;

default://在这里没有一一列出其它类型,剩下的就由阁下进行数据转换处理了,我就偷懒了^_^

return -3;//传入的数据类型不被支持

}

len = send(OnlySock, buffer, gDataLength, 0);//发送数据

delete[] buffer;

buffer = NULL;

if (len<=0)// == SOCKET_ERROR)

{

return -101;//无法发送数据,对方可能已断开连接

}

}

else

{

return 0;//网络超时

}

VariantClear(&gData);

return len;
}