初接触socket编程,当客户端连到服务器时出错

ztenv 版主
博客专家认证
2009-12-23 08:50:22
WSAETIMEDOUT: The connection has been dropped because of a network failure or because the peer system failed to respond.

先给20分,待解决后加到200分,我只能在C++版发这么多分的帖子
...全文
270 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
ztenv 版主 2009-12-31
  • 打赏
  • 举报
回复
是我自己理解协议有问题,然后就是接收数据时的问题,自己解决了,就不加份给各位了,谢谢你们的支持!!!!!!

如果有人遇到了SGIP短信网关的相应问题,我会尽量协助您解决问题的!
caicai999 2009-12-24
  • 打赏
  • 举报
回复
路过,学习了
ztenv 版主 2009-12-24
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 fetag 的回复:]
引用 19 楼 lianshaohua 的回复:
貌似解决了,用setsockopt(...,SO_KEEPALIVE,...);虽然不建议使用SO_KEEPALIVE,但我个人感觉可以做为一个应急的办法,或在recv()的时候,屏蔽TIMEOUT这个错误。。。不知道各位大侠有没有更好的建议。谢谢!

用select()异步,然后将recv()变为非阻塞的试试看

这样当socket上有事件以后,可以开始读;并且recv()为非阻塞的模式也不会影响到其它的事件

不过从你描述的解决方案看,貌似是因为两端heart beat时间太短造成的,因为SO_KEEPALIVE默认的时

间是两小时。可能你像上面一样设置了还是会有这个问题
[/Quote]

现在我的工程再改为select可能要改动很多,我再想可不可以隔一段时间如果网络空闲,就发一个空包给服务器,让服务器给返回结果,

昨天下午也考虑过select(),对select()实在是不熟悉,我来花点时间看看,然后再改造吧,

谢谢您!
hlyces 2009-12-23
  • 打赏
  • 举报
回复
14楼,顶

=====
我也不懂,来围观学习的
独孤过儿 2009-12-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lianshaohua 的回复:]
出错之前,短信网关那边收到的数据是正确的,出错之后,就收不到数据了,
再有,就是短信网关也在做为客户端连接到我的程序,我的程序目前还没有写监听这一块,不知道和这个有没有关系,谢谢!
[/Quote]
我个人猜测,你们两端是把TCP的双工当成单工来用了

你们是不是这样搞的?即 假如你们是A,短信网关是B。你们先做为客户端,以B为服务器端,建立了一个

连接,标识为 1连接;然后短信网关又作为客户端,将A作为服务端,然后又建立起 2连接。这样你们发

出去的消息,都走 1连接,这个没问题,所以短信网关能正确收到;而短信网关发给你们的消息,都走2连

接,但是由于你们没有监听,自然也就没有成功建立起 2连接。所以网关发给你们的消息都发送失败了;当

达到一定次数以后,短信网关就认为你们没有响应,于是就打死了所有和你们的连接

你最好和网管的人碰一下头,了解一下你们两边的的底层连接是什么架构,需要几个socket,怎么交互,然

后再抓下接口上的消息,看一下消息的流程是什么样的,问题应该不难定位
goodname 2009-12-23
  • 打赏
  • 举报
回复
你的pSGIPSocket是阻塞的吗?
我不了解SGIP协议,这里只是问一下。
超时错误是发生在接收包头的recv上吗?
赵4老师 2009-12-23
  • 打赏
  • 举报
回复
也许是服务端代码有Bug
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复

//判断如果非正常连接状态,则不执行以下代码,

// 先接收包头部分,以确定包的大小、类型
nRecvLen = pSGIPSocket->RECV( (char *)&sgipPack.head, sizeof(sgipPack.head),nErrCode);//第一次是能接收到正常包头的,
if( nRecvLen != sizeof( sgipPack.head))
{
continue;
}
// 接收包体
nRecvLen = pSGIPSocket->RECV(sgipPack.data, ntohl( sgipPack.head.Message_Length )-sizeof(sgipPack.head),nErrCode);
if(nRecvLen == SOCKET_ERROR)
{
continue;
}//第一次也是能正确接收到包体的。。。。。。
LOG_DEBUG("RECV response");
switch (ntohl(sgipPack.head.Command_Id))
{
//发送短信回应
case nSGIP_SUBMIT_RESP:
{
SGIP_SUBMIT_RESP &smtrsp=*(SGIP_SUBMIT_RESP *)&sgipPack.data;
if (nRecvLen!=sizeof(SGIP_SUBMIT_RESP))
{//收到发短信返回包长不对
LOG_ERROR("SGIP_SUBMIT_RESP length Error:"<<nRecvLen);
break;
}
LOG_DEBUG("recv submit resp");
// 申请已经发送了的数据使用权
EnterCriticalSection( &pSGIPSocket->m_csSendingList);
std::list<SGIP_PACKAGE>::iterator iter = pSGIPSocket->m_SendedList.begin();
SGIP_PACKAGE sgipPackTemp;
while ((iter != pSGIPSocket->m_SendedList.end()))
{
sgipPackTemp =( *iter);
sgipPackTemp.t+=60;
LOG_DEBUG(ntohl(sgipPackTemp.head.Sequence_Id)<<":"<<(int)smtrsp.Result<<":"<<ntohl(sgipPack.head.Sequence_Id));//这里第一次返回都是正确的,包括发送的结果。。。。
if (sgipPackTemp.head.Sequence_Id == sgipPack.head.Sequence_Id)
{//已经发到网关
LOG_DEBUG("Send msg to SMGW:"<<ntohl(sgipPackTemp.head.Sequence_Id));
if (pSGIPSocket->m_pfnCallback != NULL)
{
//CMPP_SENDIMG sendimg;
//sendimg.dwSequence_Id = htonl(cmppPack.head.dwSequence_Id);
//sendimg.msgid = pCmpp->hton64(smtrsp.msgid);
//sendimg.byResult = smtrsp.byResult;

pSGIPSocket->m_pfnCallback(CECMPP_SEND_IMG,0,0);
}

if (smtrsp.Result !=0)
{//失败
LOG_ERROR("Send msg to SMGW Error:"<<(int)smtrsp.Result);
pSGIPSocket->FailSMSPackToLOG(sgipPackTemp);
}
{
//短信回应应答
SGIP_PACKAGE pkg;

int len=sizeof(SGIP_HEAD)+sizeof(SGIP_SUBMIT_RESP);
memset(&pkg,0,sizeof(pkg));
pSGIPSocket->InitHead(&(pkg.head),nSGIP_SUBMIT_RESP,len);

SGIP_SUBMIT_RESP resp;
memset(&resp,0,sizeof(resp));
resp.Result=smtrsp.Result;
char *pos=pkg.data;
memcpy(pos,&(pkg.head),sizeof(pkg.head));
pos+=sizeof(pkg.head);

memcpy(pos,&resp,sizeof(resp));

pSGIPSocket->m_SendingList.push_back(pkg);
}
pSGIPSocket->m_SendedList.erase(iter);
break;
}
else if (sgipPackTemp.t <= time( NULL))
{//发送的时间是超过60秒
//删除
iter = pSGIPSocket->m_SendedList.erase(iter);
if (sgipPackTemp.n >0)
{//小于三次。重发
sgipPackTemp.n--;
sgipPackTemp.IsSend = FALSE;
pSGIPSocket->m_SendingList.push_back(sgipPackTemp);
}
else
{//发三次失败

pSGIPSocket->FailSMSPackToLOG(sgipPackTemp);
}

continue;
}
iter++;
}
LeaveCriticalSection( &pSGIPSocket->m_csSendingList);
break;
}
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复
就是联通的SGIP1.2协议封装,然后把数据发送到联通短信网关模拟器,源码目前什么都没有,难道是联通短信网关模拟器的问题?
ffcs_suo 2009-12-23
  • 打赏
  • 举报
回复
学习。。
tan625747 2009-12-23
  • 打赏
  • 举报
回复
关注此贴,可不以把源代码给发过

贴上源代码
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复
我客户端一直在发数据(毫秒级),,就是在客户端接收的时候(线程不断的接收),发生如上错误;
buffaloiron 2009-12-23
  • 打赏
  • 举报
回复
是不是服务器那边设置了接收超时?超时就自动关闭当前连接~。
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复
10060错误
Wind_Runner 2009-12-23
  • 打赏
  • 举报
回复
查看一下错误码 看是什么错误
shuiqin 2009-12-23
  • 打赏
  • 举报
回复
围观学习。。
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复
出错之前,短信网关那边收到的数据是正确的,出错之后,就收不到数据了,
再有,就是短信网关也在做为客户端连接到我的程序,我的程序目前还没有写监听这一块,不知道和这个有没有关系,谢谢!
白头老汉 2009-12-23
  • 打赏
  • 举报
回复
先确认一下客户端没出错前,服务端收到的东西是不是正确的。
发送时用的是协议的缓存,一般很少出错的,尤其超时错误,感觉不大对
ztenv 版主 2009-12-23
  • 打赏
  • 举报
回复
高手呀,我也奇怪了,怎么会超时呢?我就是发一个命令,然后过几秒,也会发生这个错误,难道是服务端的问题?我正在做短信网关,下了一个短信网关的模拟器,是不是模拟器的问题?汗。。。。。
mengde007 2009-12-23
  • 打赏
  • 举报
回复
居然超时了;每个调用过程都要WsaGetLastError()看看;
加载更多回复(5)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧