关于WSAEventSelect,为什么FD_WRITE事件只响应一次啊,大家帮我看看。。。。

saliengu 上海宏代软件技术有限公司 CTO  2005-09-17 11:55:27

int main(int argc, char* argv[])
{

WSADATA wd = { 0 };

WSAStartup( MAKEWORD( 2, 0 ), &wd );



//
// Create a TCP/IP stream socket
//
SOCKET Socket;
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
printf("socket failed,error=%d",WSAGetLastError());
return 0;
}

//
// Create an event object to be used with this socket
//
WSAEVENT hEvent;
hEvent = WSACreateEvent();
if (hEvent == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() Failed,error=%d",GetLastError());
closesocket(Socket);
return 0;
}

//
// Make the socket non-blocking and
// associate it with network events
//
int nRet;
nRet = WSAEventSelect(Socket,
hEvent,
FD_READ|FD_WRITE|FD_CLOSE);

if (nRet == SOCKET_ERROR)
{
PRINTERROR("EventSelect()");
closesocket(Socket);
WSACloseEvent(hEvent);
return 0;
}


//
// Lookup host
//
// Fill in the server address structure
//
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_addr.S_un.S_addr =inet_addr("192.168.0.2");
sa.sin_port = htons(700); // Well-known HTTP port


//
// Request a connection
//
nRet = connect(Socket,
(LPSOCKADDR)&sa,
sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
nRet = WSAGetLastError();
if (nRet == WSAEWOULDBLOCK)
{
fprintf(stderr,"\nConnect would block");
}
else
{
PRINTERROR("connect()");
closesocket(Socket);
WSACloseEvent(hEvent);
return 0;
}
}

//
// Handle async network events
//
char szBuffer[256];
strcpy(szBuffer,"hello");

WSANETWORKEVENTS events;
while(1)
{
//
// Wait for something to happen
//
fprintf(stderr,"\nWaitForMultipleEvents()");
DWORD dwRet;
dwRet = WSAWaitForMultipleEvents(1,
&hEvent,
FALSE,
WSA_INFINITE,
FALSE);
if (dwRet == WSA_WAIT_TIMEOUT)
{
fprintf(stderr,"\nWait timed out");
break;
}

//
// Figure out what happened
//
fprintf(stderr,"\nWSAEnumNetworkEvents()");
nRet = WSAEnumNetworkEvents(Socket,
hEvent,
&events);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("WSAEnumNetworkEvents()");
break;
}

// //
// Handle events //
// //

// Connect event?
if (events.lNetworkEvents & FD_CONNECT)
{
fprintf(stderr,"\nFD_CONNECT: %d",
events.iErrorCode[FD_CONNECT_BIT]);

// nRet = send(Socket, szBuffer, strlen(szBuffer), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
break;
}
}

// Read event?
if (events.lNetworkEvents & FD_READ)
{
// Read the data and write it to stdout

char buf[256];
memset(buf,0,sizeof(buf));
nRet = recv(Socket, buf, sizeof(buf), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recv()");
break;
}

printf("\n");
printf(buf);

// send(Socket,szBuffer,strlen(szBuffer),0);

}

// Close event?
if (events.lNetworkEvents & FD_CLOSE)
{
fprintf(stderr,"\nFD_CLOSE: %d",
events.iErrorCode[FD_CLOSE_BIT]);
break;
}

// Write event?
if (events.lNetworkEvents & FD_WRITE)
{
send(Socket,szBuffer,strlen(szBuffer),0);
}

nRet = WSAEventSelect(Socket,
hEvent,
FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE);


}

closesocket(Socket);
WSACloseEvent(hEvent);


return 0;
}
...全文
125 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
亿云力科技 2005-09-18
FD_WRITE在连接建立的时候被触发一次,通知你可以发送数据了;然后你应该调用WSASend()来发送数据,在数据不能发送时WinSock会提示你当前操作被阻塞,并在有缓冲可以发送时以FD_WRITE消息通知你.注意FD_WRITE的消息是你通过Send操作来触发的
回复
everandforever 2005-09-18
http://dev.csdn.net/develop/article/16/16677.shtm

看看关于FD_WRITE的说明。
回复
saliengu 2005-09-17
对不起,代码略做改动,应该是这一段。。。


int main(int argc, char* argv[])
{

WSADATA wd = { 0 };

WSAStartup( MAKEWORD( 2, 0 ), &wd );



//
// Create a TCP/IP stream socket
//
SOCKET Socket;
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
printf("socket failed,error=%d",WSAGetLastError());
return 0;
}

//
// Create an event object to be used with this socket
//
WSAEVENT hEvent;
hEvent = WSACreateEvent();
if (hEvent == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() Failed,error=%d",GetLastError());
closesocket(Socket);
return 0;
}

//
// Make the socket non-blocking and
// associate it with network events
//
int nRet;
nRet = WSAEventSelect(Socket,
hEvent,
FD_READ|FD_WRITE|FD_CLOSE);

if (nRet == SOCKET_ERROR)
{
PRINTERROR("EventSelect()");
closesocket(Socket);
WSACloseEvent(hEvent);
return 0;
}


//
// Lookup host
//
// Fill in the server address structure
//
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_addr.S_un.S_addr =inet_addr("192.168.0.2");
sa.sin_port = htons(700); // Well-known HTTP port


//
// Request a connection
//
nRet = connect(Socket,
(LPSOCKADDR)&sa,
sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
nRet = WSAGetLastError();
if (nRet == WSAEWOULDBLOCK)
{
fprintf(stderr,"\nConnect would block");
}
else
{
PRINTERROR("connect()");
closesocket(Socket);
WSACloseEvent(hEvent);
return 0;
}
}

//
// Handle async network events
//
char szBuffer[256];
strcpy(szBuffer,"hello");

WSANETWORKEVENTS events;
while(1)
{
//
// Wait for something to happen
//
fprintf(stderr,"\nWaitForMultipleEvents()");
DWORD dwRet;
dwRet = WSAWaitForMultipleEvents(1,
&hEvent,
FALSE,
WSA_INFINITE,
FALSE);
if (dwRet == WSA_WAIT_TIMEOUT)
{
fprintf(stderr,"\nWait timed out");
break;
}

//
// Figure out what happened
//
fprintf(stderr,"\nWSAEnumNetworkEvents()");
nRet = WSAEnumNetworkEvents(Socket,
hEvent,
&events);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("WSAEnumNetworkEvents()");
break;
}

// //
// Handle events //
// //

// Connect event?
if (events.lNetworkEvents & FD_CONNECT)
{
fprintf(stderr,"\nFD_CONNECT: %d",
events.iErrorCode[FD_CONNECT_BIT]);

// nRet = send(Socket, szBuffer, strlen(szBuffer), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
break;
}
}

// Read event?
if (events.lNetworkEvents & FD_READ)
{
// Read the data and write it to stdout

char buf[256];
memset(buf,0,sizeof(buf));
nRet = recv(Socket, buf, sizeof(buf), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recv()");
break;
}

printf("\n");
printf(buf);

// send(Socket,szBuffer,strlen(szBuffer),0);

}

// Close event?
if (events.lNetworkEvents & FD_CLOSE)
{
fprintf(stderr,"\nFD_CLOSE: %d",
events.iErrorCode[FD_CLOSE_BIT]);
break;
}

// Write event?
if (events.lNetworkEvents & FD_WRITE)
{
send(Socket,szBuffer,strlen(szBuffer),0);
}
}

closesocket(Socket);
WSACloseEvent(hEvent);


return 0;
}
回复
peibosys 2005-09-17
FD_WRITE并非针对send的,一般是在连线成功后会触发一次或者缓冲区出现XXX也会触发
回复
qc_jrj 2005-09-17
事件只有效一次,需要重新 select
回复
saliengu 2005-09-17
这个条件可以进啊,人怎么这么少啊,看来周末又过中秋节,大家都出去玩了,来这里的人少了
回复
nuaawenlin 2005-09-17
if (events.lNetworkEvents & FD_CONNECT)
{
fprintf(stderr,"\nFD_CONNECT: %d",
events.iErrorCode[FD_CONNECT_BIT]);

// nRet = send(Socket, szBuffer, strlen(szBuffer), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
break;
}
}
断点看看能不能进入这个条件中
回复
rageliu 2005-09-17
帮顶
回复
相关推荐
发帖
网络编程
创建于2007-09-28

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
帖子事件
创建了帖子
2005-09-17 11:55
社区公告
暂无公告