求助:socket通信

AZone2008 2010-10-26 10:14:55
我用VC开发了一个小程序,作为SOCKET客户端,用于与另一个服务器端应用程序进行SOCKET通信
但是某些时候会突然发生异常,我的程序仍可以发送信息到服务器,却接收不到服务器返回的信息
请教各位高手,可能的原因是什么?
另外我用抓包软件看过了,服务器端返回的信息发送到了客户端,客户端无应答,所以看上去就是接收不到服务器返回的信息。这种情况只是随机发生,且发生之后会连续收不到消息。
...全文
128 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
AZone2008 2010-11-09
  • 打赏
  • 举报
回复
请版主帮忙删除“回复于:2010-10-29 15:42:11”的帖子,谢谢!
AZone2008 2010-10-29
  • 打赏
  • 举报
回复
请大侠们帮忙分析分析,谢啦!
AZone2008 2010-10-29
  • 打赏
  • 举报
回复
void CCommSocket::OnConnect(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class

CSocket::OnConnect(nErrorCode);
}
void CCommSocket::OnReceive(int nErrorCode)
{
//收到数据自动响应
CSocket::OnReceive( nErrorCode );

CString rSocketAddress;
UINT rSocketPort;
CSocket::GetPeerName( rSocketAddress, rSocketPort );
if( !IsRecv_R )
{
//工控机端代码
( ( CRecvClass * )pRecv )->ReceiveMessageInfo( this, rSocketAddress, rSocketPort );
}
else
{
//接收机端代码
( ( CReceiver * )pRecv )->ReceiveMessageInfo( this, rSocketAddress, rSocketPort );
}
}
void CCommSocket::OnClose(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
CSocket::OnClose( nErrorCode );
CString rSocketAddress;
UINT rSocketPort;
CSocket::GetPeerName( rSocketAddress, rSocketPort );
if( !IsRecv_R )
{
unsigned int AddrNum;
AddrNum = inet_addr( rSocketAddress.GetBuffer( 0 ) );

CRecvClass *pTmp = NULL;
pTmp = ( CRecvClass * )pRecv; //临时记住传过来的主设备指针
( ( CRecvClass * )pRecv )->CloseSocket();//最后删除自己
pTmp->m_pSocket = NULL; //将主类中的m_pSocket指针清空
::SendMessage( pTmp->Inhand, Message_CloseSocket, AddrNum, 0 );
}
else
{
unsigned int AddrNum;
AddrNum = inet_addr( rSocketAddress.GetBuffer( 0 ) );

CReceiver *pTmp = NULL;
pTmp = ( CReceiver * )pRecv; //临时记住传过来的主设备指针
( ( CReceiver * )pRecv)->CloseSocket(); //最后删除自己
pTmp->m_pSocket = NULL; //将主类中的m_pSocket指针清空
::SendMessage( pTmp->Inhand, Message_CloseSocket, AddrNum, 0 );
}
}
int CCommSocket::SendMsg(char* pSend,long Length)
{
int i = CAsyncSocket::Send( pSend, Length, 0 );
if( i == SOCKET_ERROR ) int e = GetLastError();
return i;
}
CCommSocket* m_pSocket;
BOOL CReceiver::InitSocket( int NetPort )
{
if ( !AfxSocketInit() )
{
AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
return FALSE;
}
else
{
m_pLstnSocket = new CListeningSocket(this, TRUE );
if(m_pLstnSocket->Create(NetPort))
{
m_pLstnSocket->Listen();
}
return TRUE;
}
}
void CReceiver::fill_icmp_data(char* pICMPData,int nDataSize)
{
ICMPHEADER *pICMPHdr;
char *pDataPart;
pICMPHdr = (ICMPHEADER*)pICMPData;
pICMPHdr->i_type = ICMP_ECHO;
pICMPHdr->i_code = 0;
pICMPHdr->i_id = (USHORT)GetCurrentProcessId();
pICMPHdr->i_cksum = 0;
pICMPHdr->i_seq = 0;
pDataPart = pICMPData + sizeof(ICMPHEADER);
// Place some junk in the buffer.
memset(pDataPart, 'E', nDataSize - sizeof(ICMPHEADER));
}

BOOL CReceiver::ConnectSocket(LPCTSTR lpszAddress,int port)
{
if(!Ping(lpszAddress))
{
CString devstr;
CString addr=lpszAddress;
// devstr="连接"+addr+"失败!!!";
devstr = theApp.oPC.m_strArray.GetAt( 250 ) + addr + theApp.oPC.m_strArray.GetAt( 251 ) + "!!!";
return FALSE;
}
if(m_pSocket!=NULL)return TRUE;
m_pSocket=new CCommSocket(this, TRUE );
if( !m_pSocket->Create() )
{
AfxMessageBox((LPCTSTR)"Faild to Create a socket!",NULL,MB_OK);
delete m_pSocket;
m_pSocket=NULL;
return FALSE;
}
if( !m_pSocket->Connect( lpszAddress, port ) )
{
CString devstr;
CString addr=lpszAddress;
// devstr="连接"+addr+"失败!!!";
devstr = theApp.oPC.m_strArray.GetAt( 250 ) + addr + theApp.oPC.m_strArray.GetAt( 251 ) + "!!!";
delete m_pSocket;
m_pSocket=NULL;
return FALSE;
}
return TRUE;
}
USHORT CReceiver::checksum(USHORT *buffer, int size)
{
unsigned long cksum = 0;
while (1 < size)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
cksum += *(UCHAR*)buffer;

cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
BOOL CReceiver::Ping(CString IPaddr)
{
char* m_pICMPData=NULL,*m_pRecvBuf=NULL,*pICMPData=NULL;
sockaddr_in m_saDest;
UINT m_uSeqNo = 0;
int nDataSize=64;
m_pICMPData=new char[nDataSize];
m_pRecvBuf=new char[nDataSize];
CString str;
hostent *hp;
int timeout;
unsigned int addr=0;
int nLength;
unsigned int dw=0, m_sockRaw;
m_sockRaw = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(INVALID_SOCKET == m_sockRaw)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
timeout=1000;
int i=setsockopt(m_sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
i=setsockopt(m_sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));
if(SOCKET_ERROR==i)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
memset(&m_saDest,0,sizeof(m_saDest));
nLength=sizeof(dw);
addr=inet_addr(IPaddr);
if(INADDR_NONE==addr)
{
if(NULL==(hp=gethostbyname(IPaddr)))
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
else
{
m_saDest.sin_family=hp->h_addrtype;
memcpy(&(m_saDest.sin_addr),hp->h_addr_list,hp->h_length);
}
}
else
{
m_saDest.sin_family=AF_INET;
m_saDest.sin_addr.s_addr=addr;
}
nDataSize = 64 + sizeof(ICMPHEADER);//m_uPacketSize
m_pICMPData = new char[nDataSize];
m_pRecvBuf = new char[nDataSize + MAXIPHEADER];
memset(m_pICMPData, 0, nDataSize);
fill_icmp_data(m_pICMPData, nDataSize);
((ICMPHEADER*)m_pICMPData)->i_cksum = 0;
((ICMPHEADER*)m_pICMPData)->timestamp = GetTickCount();
((ICMPHEADER*)m_pICMPData)->i_seq = 0xffff & (m_uSeqNo ++);
((ICMPHEADER*)m_pICMPData)->i_cksum = checksum((USHORT*)m_pICMPData,
nDataSize);
int nWrite=sendto(m_sockRaw,m_pICMPData,
nDataSize,0,(struct sockaddr*)&m_saDest,sizeof(m_saDest));
if(SOCKET_ERROR==nWrite)
{
int nError=WSAGetLastError();
if(WSAETIMEDOUT==nError)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
else
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
}
if (nWrite < nDataSize)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
int ii=sizeof(m_saDest);
i=recvfrom(m_sockRaw,m_pRecvBuf,nDataSize,0,(struct sockaddr*)&m_saDest,&ii);
if(i==SOCKET_ERROR)
{
i=WSAGetLastError();
if(i==WSAETIMEDOUT)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return FALSE;
}
if(i==WSAECONNREFUSED)//
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
}
if(i==WSAENETUNREACH)
{
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
}
return TRUE;
}
closesocket(m_sockRaw);
m_sockRaw=INVALID_SOCKET;
return TRUE;
}
void CReceiver::CloseSocket()
{
//关闭指定IP地址

//
// AFX_MANAGE_STATE(AfxGetStaticModuleState());

if(m_pSocket!=NULL)
{
m_pSocket->Close();
delete m_pSocket;
m_pSocket=NULL;
}
if(DataNumBuffer!=NULL)
{
delete DataNumBuffer;
DataNumBuffer=NULL;
}
if (databody!=NULL)
{
delete databody;
databody=NULL;
}
RecvHeadNum = 0; //*次接收到的命令头数量
RecvDataNum=0; //*次接收到的命令Data字段数量
DataNum=0;
CmdSeq=0; //前指令序号,为CMapWordToPtr定义,1--10000,总共10000条命令
ReadCmdSeq=0; //*送指令序列
RecvHead=NULL;
POSITION pos1 = m_CmdLst.GetStartPosition();
while(pos1)
{
WORD str;
void *pTemp;
m_CmdLst.GetNextAssoc(pos1,str,pTemp);
delete pTemp;
pTemp = NULL;
}
m_CmdLst.RemoveAll();
}
BOOL CReceiver::SendMessageInfo(char *pSend, long Length)
{
if(m_pSocket==NULL)return FALSE;
if(pSend=="")return FALSE;
int i=m_pSocket->SendMsg(pSend,Length);

if(i==SOCKET_ERROR)
{
CloseSocket();
return FALSE;
}
return TRUE;
}

void CReceiver::ReceiveMessageInfo( CCommSocket* pCommSocket,CString& sSocketAddress, UINT& iSocketPort ) //接收数据流程视发送方式改变需要调整
{
unsigned int IPaddr;
IPaddr = inet_addr( sSocketAddress.GetBuffer( 0 ) );
RecvHeadNum = pCommSocket->Receive( &DataHeadBuffer[0], 56 ); //一次最多接收1000字节
if( RecvHeadNum == 56 ) //命令头长度正确,继续读报文内容
{
int iData[2];
memcpy( &iData[0], DataHeadBuffer, sizeof(int)*2 );
if( iData[0] != 0xaa55aa55 || iData[1] != 0xbb44bb44 )
{
//*果帧头错误,就丢掉该包数据
return;
}
memcpy( DataBuffer, &DataHeadBuffer[8], 48 ); //将头考出
RecvHead=( CMD_HEAD* )(DataBuffer);

//处理

if( DataNum == 0 )
{
//*:只有数据头,没有数据体的指令加入指令表
if(databody!=NULL)
{
delete databody;
databody=NULL; //清空数据体指针
}

if( CmdSeq == 10 )CmdSeq=1;
CmdSeq++;
SetInDataList(CmdSeq,RecvHead);
if( ReadCmdSeq != CmdSeq )
{
//*果读数在后面
if( ReadCmdSeq == 10 )ReadCmdSeq=1;
ReadCmdSeq++;
iRecvLength = DataNum; //将DataSize的长度赋值给类变量,便于主控程序申请缓存空间大小用
::SendMessage( Inhand, Message_RecvHead, IPaddr, iSocketPort );
}
return ;
}
else if( DataNum > 0 && DataNum < 100000 )
{
DataNumBuffer=new char[DataNum]; //数据缓冲区,双字
RecvDataNum=pCommSocket->Receive( &DataNumBuffer[0], DataNum );
if( RecvDataNum == DataNum )
{
//接收完毕,注:Head+body处理
char *DataBodyBuffer=new char[DataNum];
memcpy( DataBodyBuffer, DataNumBuffer, DataNum );
databody = DataBodyBuffer;
if( CmdSeq==10 ) CmdSeq=1;
CmdSeq++;
SetInDataList(CmdSeq,RecvHead);
if( ReadCmdSeq != CmdSeq )
{
//如果读数在后面
if(ReadCmdSeq==10)ReadCmdSeq=1;
ReadCmdSeq++;
iRecvLength = DataNum; //将DataSize的长度赋值给类变量,便于主控程序申请缓存空间大小用
::SendMessage( Inhand, Message_RecvHead, IPaddr, iSocketPort );
}
delete DataNumBuffer; //释放零时缓存区
DataNumBuffer=NULL; //清空指针
return ;
}
else if( RecvDataNum == 0 ) //没有读到数据
{
}
else if( RecvDataNum == SOCKET_ERROR ) //出现读数据错误
{
}

}
else if( DataNum < 0 )
{
AfxMessageBox( "错误:数据长度小于0!", MB_OK);

return ;
}
else if( DataNum >= 100000 )
{
AfxMessageBox( "错误:数据长度大于100K!", MB_OK);
return ;
}
}
else if( RecvHeadNum == 0 ) //没有读到数据
{
}
else if( RecvHeadNum == SOCKET_ERROR ) //出现读数据错误
{
}
}
chuanzhang5687 2010-10-26
  • 打赏
  • 举报
回复
发代码好吗
AZone2008 2010-10-26
  • 打赏
  • 举报
回复
怎么看缓冲呀?
bourbon1795 2010-10-26
  • 打赏
  • 举报
回复
缓冲是否够用
lonyjianhui 2010-10-26
  • 打赏
  • 举报
回复
客户端代码有误,请用抓包查看客户端有没有接收到数据,还有,你的客户端是异步接收,还是同步,还是异步回调,有没有处理丢包,粘包问题等等,所以没有你的客户端代码,这问题就难解决了

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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