int BaseSocket::mytcpsend(const char *str,int len)
{
sendlen = send(mysocket,str,len,SEND_FLAG);
if(sendlen == -1 || sendlen > len)
{
showSktError();
return -1;
}
return 0;
}这是很简单的发送数据的方法,众所周知,在异步模式下发送数据太快就会出现WSAEWOULDBLOCK错误。我知道在MFC下响应FD_WRITE就行,但现在这是一个单纯的c++命令行程序,而且是在UNIX下用的,所以没有MFC,没有窗口,没有消息机制, 应该怎么办呀?
{
sendlen = send(mysocket,str,len,SEND_FLAG);
if(sendlen == -1 || sendlen > len)
{
showSktError();
return -1;
}
return 0;
}这是很简单的发送数据的方法,众所周知,在异步模式下发送数据太快就会出现WSAEWOULDBLOCK错误。我知道在MFC下响应FD_WRITE就行,但现在这是一个单纯的c++命令行程序,而且是在UNIX下用的,所以没有MFC,没有窗口,没有消息机制, 应该怎么办呀?
WSAEventSelect模型类似WSAAsynSelect模型,但最主要的区别是网络事件发生时会被发
送到一个事件对象句柄,而不是发送到一个窗口。使用步骤如下:
a、 创建事件对象来接收网络事件:
#define WSAEVENT HANDLE
#define LPWSAEVENT LPHANDLE
WSAEVENT WSACreateEvent( void );该函数的返回值为一个事件对象句柄,它具有两种工作状态:已传信(signaled)和未传信
(nonsignaled)以及两种工作模式:人工重设(manual reset)和自动重设(auto reset)。默认未
未传信的工作状态和人工重设模式。b、将事件对象与套接字关联,同时注册事件,使事件对象的工作状态从未传信转变未
已传信。
int WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );
s为套接字
hEventObject为刚才创建的事件对象句柄
lNetworkEvents为掩码,定义如上面所述c、I/O处理后,设置事件对象为未传信BOOL WSAResetEvent( WSAEVENT hEvent );
Hevent为事件对象成功返回TRUE,失败返回FALSE。d、等待网络事件来触发事件句柄的工作状态:DWORD WSAWaitForMultipleEvents( DWORD cEvents,
const WSAEVENT FAR * lphEvents, BOOL fWaitAll,
DWORD dwTimeout, BOOL fAlertable );
lpEvent为事件句柄数组的指针
cEvent为为事件句柄的数目,其最大值为WSA_MAXIMUM_WAIT_EVENTS
fWaitAll指定等待类型:TRUE:当lphEvent数组重所有事件对象同时有信号时返回;
FALSE:任一事件有信号就返回。
dwTimeout为等待超时(毫秒)
fAlertable为指定函数返回时是否执行完成例程对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents的返回值,减去
预声明值WSA_WAIT_EVENT_0,得到具体的引用值。例如:nIndex=WSAWaitForMultipleEvents(…);
MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];
e、判断网络事件类型:int WSAEnumNetworkEvents( SOCKET s,
WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );
s为套接字
hEventObject为需要重设的事件对象
lpNetworkEvents为记录网络事件和错误代码,其结构定义如下:typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
f、关闭事件对象句柄:BOOL WSACloseEvent(WSAEVENT hEvent);
调用成功返回TRUE,否则返回FALSE。
do{
Sleep(20);
sendlen = send(mysocket,str,len,SEND_FLAG);
}
while(sendlen == -1 && WSAGetLastError() == WSAEWOULDBLOCK)所以我怀疑是socket发生了类似死锁一样的情况,始终无法去做写操作了,这有可能是什么原因造成的啊?会不会是一个socket上同时发生读和写操作啊?
Resource temporarily unavailable.
This error is returned from operations on non-blocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a non-fatal error, and the operation should be retried later. It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a non-blocking SOCK_STREAM socket, since some time must elapse for the connection to be established.