用Winsock通信过程中,什么情况下会发生block?
客户端系统缓存不够?或者接收方来不及接收?哪位大侠把可能发生阻塞的情况列举一下,谢谢了。
(主要是局域网应该中可能的阻塞,网络硬件条件是很好的,软件系统是win98和win2000)
客户端系统缓存不够?或者接收方来不及接收?哪位大侠把可能发生阻塞的情况列举一下,谢谢了。
(主要是局域网应该中可能的阻塞,网络硬件条件是很好的,软件系统是win98和win2000)
即使用SELECT判断,也还是会2、SEND和RECV都是会的3、CLOSE也会。
所以说可能不存在那种一方发的信息太多了,所以另一方面缓冲溢出了。
1.用研华的数据采集卡1711L,中断方式单路采集数据,采集非常稳定。
2.另外用Winsock API写了个通信程序,采用的是SOCK_STREAM协议,服务器端选的是异步方式,WSAAsyncSelect(ConnectClient,m_hWnd,WM_READCLOSE,FD_READ|FD_CLOSE); 服务器每次收到数据,都立即显示出来。为了提高通信速度,我放弃了Nagle算法,
int bNodelay = 1;
int err;
err = setsockopt(
sConnect,
IPPROTO_TCP,
TCP_NODELAY,
(char *)&bNodelay,
sizoeof(bNodelay));
要求没10ms通信一次,用的是多媒体定时器。程序写好后,运行非常稳定,我试过一个小时,感觉不到延迟,并且没有阻塞,没有丢点(我发送和接收都有记录)。3.于是,我把两个程序写到一起(通信的服务器不变,把采集程序和通信的客户端程序集成起来),问题出现了,结果通信一小段时间后,服务器段接收不到数据,而客户段再过一段时间后报告block。请问问题出在哪里?该怎么解决?谢谢各位大侠了。
我遇到过这种情况。
初始化的部分是这样:
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,1),&wsaData)) //调用Windows Sockets DLL
{
WSACleanup();
return;
}
ServerSocket=socket(PF_INET,SOCK_STREAM,0); //创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信if(ServerSocket == INVALID_SOCKET)
{
return;
}DWORD dwip;
if((dwip=inet_addr(ip))==INADDR_NONE)
{
return;
}
sockStruct.sin_family=AF_INET; //使用TCP/IP协议
sockStruct.sin_port = htons(8001);
sockStruct.sin_addr.S_un.S_addr = dwip;if(connect(ServerSocket,(LPSOCKADDR)&sockStruct,sizeof(sockStruct)) == SOCKET_ERROR)
{
return;
}然后设定多媒体定时器,每10ms发送一次,代码是这样:
if(send(ServerSocket,(char *)&commPackage,sizeof(COMM_DATA_PACKAGE),0) == SOCKET_ERROR)// recv(ServerSocket,buf,sizeof(buf),0);
{
AfxMessageBox("发送数据发生错误。");
}
WSADATA wsaData;
int iErrorCode;
if (WSAStartup(MAKEWORD(2,1),&wsaData)) //调用Windows Sockets DLL
{
AfxMessageBox("Winsock无法初始化!");
WSACleanup();
return;
}
ServerSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); //创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信 if(ServerSocket == INVALID_SOCKET)
{
list.InsertString(0,"无法创建服务器socket!");
return;
} m_sockServerAddr.sin_family = AF_INET;
m_sockServerAddr.sin_addr.s_addr = INADDR_ANY; //向所有的IP地址发送消息
m_sockServerAddr.sin_port = htons(8001); if (bind(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,sizeof(m_sockServerAddr)) == SOCKET_ERROR) //与选定的端口绑定
{
AfxMessageBox("无法绑定服务器。");
return;
} list.InsertString(0,"服务器端口:8001.");
初始化如下:
WSADATA wsaData;
int iErrorCode;
if (WSAStartup(MAKEWORD(2,1),&wsaData)) //调用Windows Sockets DLL
{
WSACleanup();
return;
} ServerSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); //创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信
if(ServerSocket == INVALID_SOCKET)
{
return;
} m_sockServerAddr.sin_family = AF_INET;
m_sockServerAddr.sin_addr.s_addr = INADDR_ANY; //向所有的IP地址发送消息
m_sockServerAddr.sin_port = htons(8001); if (bind(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,sizeof(m_sockServerAddr)) == SOCKET_ERROR) //与选定的端口绑定
{
return;
} iErrorCode=WSAAsyncSelect(ServerSocket,m_hWnd,WM_CLIENT_ACCEPT,FD_ACCEPT);
// 产生相应传递给窗口的消息为WM_SERVER_ACCEPT ,这是自定义消息 if (iErrorCode == SOCKET_ERROR)
{
return;
} if (listen(ServerSocket,2) == SOCKET_ERROR) //开始监听客户连接请求
{
return;
}在相应FD_ACCEPT的窗口函数OnAccept()中,代码如下:
LRESULT CRecvDlg::OnAccept(WPARAM wParam,LPARAM lParam)
{
if (WSAGETSELECTERROR(lParam))
{
return 0L;
} if(WSAGETSELECTEVENT(lParam) == FD_ACCEPT)//如果
{
Client = accept(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,0);
if (Client == INVALID_SOCKET)
{
return 0L;
} WSAAsyncSelect(Client,m_hWnd,WM_CLIENT_READCLOSE,FD_READ|FD_CLOSE);
} return 0L;
}
在相应FD_READ|FD_CLOSE的窗口函数中
LRESULT CRecvDlg::OnReadClose(WPARAM wParam,LPARAM lParam)
{//自定义的关闭与缓冲区有消息
CString str;
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
if(recv(Client,(char *)&commPackage,sizeof(COMM_DATA_PACKAGE),0) == SOCKET_ERROR)
{
AfxMessageBox("recieive data failed!");
return 0;
}
}
}
/======================
然后设定多媒体定时器,每10ms发送一次,代码是这样:
if(send(ServerSocket,(char *)&commPackage,sizeof(COMM_DATA_PACKAGE),0) == SOCKET_ERROR)// recv(ServerSocket,buf,sizeof(buf),0);
{
AfxMessageBox("发送数据发生错误。");
}和
//==========================
case FD_READ:
if(recv(Client,(char *)&commPackage,sizeof(COMM_DATA_PACKAGE),0) == SOCKET_ERROR)
{
AfxMessageBox("recieive data failed!");
return 0;
}
}
这两个地方看看出错码到底是多少?而且你说把程序分开运行得很好。
合起来有问题,这个地方我也感到湖涂,
因为你用的是多媒体定时器呀这东东就跟中断处理差不多了。顺便UP一下