一个回声程序,客户端发送1m的数据,发送两次成功返回,在发送两次成功发送,但不能返回,在点击发送以后都不能发送。客户端这时中断连接,服务器端弹出10055:WSAENOBUFS。客户端是非阻塞式的,服务器是阻塞式的。
客户端:
char sendBuf[1024*1024];
char recvBuf[1024*1024];
void CChatDlg::OnBtnSend() //发送数据按钮
{
CString str;
         
……
         sendlen=send(m_socket_TCP,sendBuf,SEND_MAX_BYTE,0);
……
}
void CChatDlg::OnReadTCP(WPARAM wParam,LPARAM lParam)//读取事件的发生
{
…………
switch(LOWORD(lParam))
{
case FD_READ:

if(recvmaxbyte>0)
{
recvlen=recv(m_socket_TCP,&recvBuf[idx],recvmaxbyte,0);//接收数据
if(recvlen==0)
{
return;
}
else if(SOCKET_ERROR==recvlen)
{
MessageBox("TCP接收数据失败!");
return;
}
recvsum+=recvlen;
idx+=recvlen;
recvmaxbyte-=recvlen;
}
if(recvmaxbyte==0)
{
…………
}


}
}
服务器端:
DWORD WINAPI CEmulatorDlg::TCPPro(LPVOID lpParameter)\\TCP接受发送线程
{
……
CEmulatorDlg *dlg=(CEmulatorDlg *)AfxGetApp()->GetMainWnd();

if(listen(dlg->m_socket_TCP,5)!=0)
{
return 0;
}

while(1)
{

socketaccept=accept(dlg->m_socket_TCP,(sockaddr*)&addrPC,&len);
……
while(SOCKET_ERROR!=recvinfo)
{
recvinfo=recv(socketaccept,recvBuf,sizeof(recvBuf),0);
if(recvinfo!=0)
{
sendinfo=send(socketaccept,recvBuf,recvinfo,0);
memset(recvBuf,0,RECV_MAX_BYTE);
……
}
if(SOCKET_ERROR==recvinfo)
{
switch(WSAGetLastError())
{
case 10055: //WSAENOBUFS          AfxMessageBox("接收缓存空间不够!");
break;
                                     ……
}
return 0;
}
}
}
return 0;
}

解决方案 »

  1.   

    你的软件处理模式有问题。
    先是客户端狂发信息,然后读取信息。
    服务器端阻塞式收取,收取后马上发送返回,但是因为客户端还没开始收取呢,所以服务器端的
    程序阻塞在send的地方,你的客户端还在发送,这样淹没了服务器端的缓存,所以报错了。──────────────────────
    国内专业的ACE论坛开通:
    www.acejoy.com 
    www.acedevelop.com
    涉及ACE使用和开发,服务器端软件的设计,P2P技术,
    网络编程等内容。
    欢迎加入,大家一起交流、学习成长!
      

  2.   

    全双工操作,是可以同时进行发送和收取,缓冲不同。但问题是操作是阻塞的,你进行了发送,就不能收取了,所以服务器的缓冲被淹没了。什么时候收取,依赖于OS的机制和调度和实现了。
    建议你研究一下windows 网络编程,就不会写出这样的程序了。
      

  3.   

    查到错在哪了:客户端加了下面的代码。
           if(recvByteNum==0)
    {

    //加了以下三行代码
    recvsum=0;
    idx=0;
    recvByteNum=RECV_MAX_BYTE;
    }
    我就不说什么了,这么弱智的错误!