分享
 
 
 

论软件接口中几种底层通讯的实现

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

论软件接口中几种底层通讯的实现

李伟华 msn:liweihua200204@hotmail.com

2005-3-28

一、概述

软件接口是实现一个系统跟另外系统进行信息交互的桥梁,在不同的系统之间,根据系统的关联程度的不同存在紧耦合和松耦合两种:紧耦合要求接口响应反应快,消息不能阻塞;松耦合对响应反应要求比较低。本人主要讨论紧耦合接口通讯实现,在目前应用中,Socket、中间件、SOAP等都用相应的应用,但是应用中发现各通讯方式有自己固有的特征,“适合的才是最好的”,这是真理。

在接口和系统信息交互的过程中,两种模式使用得很普遍:同步调用和异步调用,同步调用要求接口发出请求消息后必须等待服务端系统的应答消息,接口阻塞直至超时;异步调用则发出请求消息后,接口可以从事其它处理,定时轮询服务端应答消息和消息或事件通知。同步方式简单,但是很容易造成接口阻塞,造成消息积压超时。

二、技术实现

1、 Socket通讯

Socket通讯相对来说是很古老的通讯方式,也是最常用的通讯方式。Socket通讯有阻塞和非阻塞两种方式。在同步方式,采用阻塞编程比较简单,但是为了防止接口阻塞,我们需要设置Socket超时,因此可以使用Socket的SELECT模型(参考如下示例代码):

ReceLen=0;

CurReceLen=0;

for(;;)

{

iResult=select(0,&fdread,NULL,NULL,&timeout);

if(iResult==0)

{

AfxMessageBox("接收应答消息超时!!!",MB_OK|MB_ICONERROR);

closesocket(Socket);

return FALSE;

}

CurReceLen = recv(Socket, oBuf+ReceLen, len, NO_FLAG_SET);

if((CurReceLen>0) && (CurReceLen != SOCKET_ERROR))

{

oBuf[ReceLen+CurReceLen]='\0';

memcpy((char *)&MsgLen,oBuf,sizeof(WORD32));

MsgLen=ntohl(MsgLen);

if(ReceLen+CurReceLen==MsgLen)

{

ReceLen+=CurReceLen;

break;

}

ReceLen+=CurReceLen;

}

}

在异步方式下,采用非阻塞方式实现比较方便,在非阻塞方式下可使用WSAAsyncSelect模型和WSAEventSelect模型:WSAAsyncSelect模型基于消息,WSAEventSelect模型基于事件,下面的示例代码设置了Socket进行读写和关闭操作的消息:

status = WSAAsyncSelect(TempSocket, hWnd, WSA_READ, FD_READ | FD_CLOSE | FD_WRITE);

if (status == SOCKET_ERROR)

{

WriteLogFile("Set stream socket module fail!!!IP(%s),Port(%d) and error(%d)",GetIPAddr((PeerMap+node)->IPAddr),(PeerMap+node)->PeerPortNo,WSAGetLastError());

CloseSocket(TempSocket,__LINE__,__FILE__);

return FALSE;

}

无论使用阻塞方式或非阻塞方式编程,需要重点考虑的一个问题:粘包现象,即应用发送两个或以上的数据包,在Socket通讯层将数据包合并成一个发送出去,因此接收端收到数据包以后需要对数据包根据应用定义的长度进行拆分,否则导致应用层丢包。

2、 中间件通讯

目前中间平台也比较多,我所使用的中间件有BEA的Tuxedo和东方通的TongEasy,TongEasy我就不说了,主要讨论一下Tuxedo。BEA Tuxedo系统提供九种通信模式:

⑴.同步Request/Response模式;

⑵.异步Request/Response模式;

⑶.嵌套调用;

⑷.调用转发;

⑸.会话通信;

⑹.主动消息通告;

⑺.基于事件的通信;

⑻.基于队列的通信;

⑼.使用事务。

同步请求/应答方式比较简单,因此在应用中也使用得相当多。但是同步请求/应答方式在服务端服务端反应比较慢时造成阻塞,如果使用了多线程方式,不管Tuxedo采用长连接还是短连接均容易造成线程挂起,不能再进行后续处理,很多情况需要程序重启。采用异步方式不会造成阻塞,但需要去查询是否有应答消息,下面的代码实现了使用异步函数实现同步调用的功能,增加了超时处理,这样不会导致程序阻塞:

int tpcallex(char *svc, char *idata, long ilen, char **odata, long *olen, long flags, long timeout)

{

const int err_invoke_result = -1;

int iHandler=0;

int iResult=0;

int iTimeOut=timeout;

iHandler = tpacall((char *)svc, (char *)idata, ilen, (long)TPNOBLOCK);

if(iHandler == err_invoke_result)

{

return iHandler;

}

while(iTimeOut>0)

{

iResult = tpgetrply(&iHandler, (char **)odata, olen, (long)TPNOBLOCK);

if(iResult == err_invoke_result)

{

Sleep(10);

iTimeOut -= 10;

continue;

}

break;

}

if(iTimeOut<=0)

{

tpcancel(iHandler);

return err_invoke_result;

}

return iHandler;

}

如果要增加接口的处理能力,使用多线程方式会存在隐患,最好的方式是采用多进程,不过存在如何消息均衡的问题。

3、 SOAP通讯

SOAP作为一种协议,同服务端Web Service进行通讯。IBM和微软提供了SOAP协议的SDK,我使用的是微软的SOAP Toolkit3.0,这是基于COM的一套组件,因此具有COM的特征,在调用参数的处理,windows和unix顺序恰好相反,下面的代码实现了调用一个Web Service:

if(!m_bFlatType)

{

for(i=paramNum,j=0;i>j;i--,j++)

{

VARIANTARG argTemp;

VariantInit(&argTemp);

argTemp=va[i-1];

va[i-1]=va[j];

va[j]=argTemp;

}

}

params.cArgs = paramNum;

params.rgvarg = va;

params.cNamedArgs = 0;

params.rgdispidNamedArgs = NULL;

hr = SoapConnect.pSoapClient[index]->Invoke(dispidFn, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params,

&result, 0, 0);

if(FAILED(hr))

{

HandleHResult(_T("Invoke of "+strService+" method failed."), hr);

VariantClear(&result);

for(i=0;i<MAX_PARAM_NUM;i++) VariantClear(&va[i]);

SysFreeString(bstrServiceName);

CoUninitialize();

return FALSE;

}

三、总结

在三种通讯方式中,各有优缺点,但是主要还在于服务端采用什么技术方案来实现,接口必须对应采用相应的通讯模式。

除了上面的通讯模式,当然还有很多其它的方式,如管道、消息队列等,目前我在紧耦合的接口中使用得不多。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有