请教大家WSARecv的用法,程序流程如下:SOCKET s;省略连接服务器WSAEventSelect(....);WSAEnumNetworkEvents(...);if (pNetworkEvents.lNetworkEvents & FD_READ)//有数据可以读取
{
     int ret = WSARecv(...., NULL);//问题就在这里,WSARecv调用后程序直接返回 0,我要用什么函数或者什么方法知道已经收到数据了呢?并且开始处理数据}因为我的应用比较特殊,所以不能使用recv函数,问题解决立刻散分,谢谢

解决方案 »

  1.   

    Simple IP samples. 
    -----------------simples.c:
    ----------This is a very simple-minded TCP/UDP server. It listens on a specified port
    for client connections. When a client connects, the server receives data,
    echoes it back to the client and closes the connection.Usage:
    simples -p <protocol> -e <endpoint> -i <interface>Where,
     Protocol is one of TCP or UDP, Endpoint is the port number to listen on, Interface is the IP address to bind to (for multihomed machines this can be
       specified. Machines with just one network interface will not need this
       parameter, typically).
    Note:
    ---- There are differences in the way TCP and UDP "servers" can be written. For
    TCP, the paradigm of bind(), listen() and accept() is widely implemented. 
    For UDP , however, there are two things to consider:    1. listen() or accept() do not work on a UDP socket. There are APIs
    that are oriented towards connection establishment, and are not applicable
    to datagram protocols. To implement a UDP server, a process only needs to
    do recvfrom() on the socket that is bound to a well-known port. Clients
    will send datagrams to this port, and the server can process these. 2. Since there is no connection esablished, the server must treat each
    datagram separately.
    simplec.c
    ---------A simple TCP/UPD client application. It connects to a specified IP address and
    port and sends a small message. It can send only one message, or loop for a
    specified number of iterations, sending data to the server and receiving a
    response.Usage:
    simplec -p <protocol> -n <server> -e <endpoint> -l <iterations>Where,
     Protocol is TCP or UDP.
     Server is the IP address/ name of the server
     Endpoint is the port number the server is listening on
     iterations specifies how many messages to send. 
     
     '-l' without any arguments will cause the client to send & receive  messages 
     until interrupted by Ctrl-C.
     This option *will not* work against simples.exe as the TCP server. This is
     because simples.exe closes the socket after one transaction. You will need
     something like the overlap sample which keeps the socket open indefinitely.
    Note:
    ----
    As explained for simples.c, there is no concept of a connection in UDP
    communications. However, we can use connect() on a UDP socket. This
    establishes the remote (IPaddr, port) to used when sending a datagram.
    Thus, we can use send() instead of sendto() on this socket. This makes the code exactly the same for UDP and TCP sockets. However, it
    must be realized that this is still connectionless datagram traffic for
    UDP sockets, and must be treated as such.
    ioctl.c
    -------This is a TCP-only server that shows how to use select() in a Win32 console
    application. The server creates a socket to listen() on, and makes it
    non-blocking with ioctlsocket(), and then calls select().
    When a client connects to this server, the server multiplexes between the new
    connection and the original listening socket, again using select(). 
    As soon as a new connection is established, the server breaks the connection
    with the first client.Usage: (same as simples)

    This sample illustrates the point that select() is not very useful in Win32
    applications, since it is difficult to keep track of every open socket and
    test it for readiness when select() returns.Applications should use WSAAsyncSelect for GUI-based event
    selection, or Overlapped I/O and native Win32 wait functions to achieve the
    same effect as select.
      

  2.   

    // Module Name: eventselect.cpp
    //
    // Description:
    //
    //    This sample illustrates how to develop a simple echo server Winsock
    //    application using the WSAEventSelect() I/O model. This sample is
    //    implemented as a console-style application and simply prints
    //    messages when connections are established and removed from the server.
    //    The application listens for TCP connections on port 5150 and accepts them
    //    as they arrive. When this application receives data from a client, it
    //    simply echos (this is why we call it an echo server) the data back in
    //    it's original form until the client closes the connection.
    //
    // Compile:
    //
    //    cl -o eventselect eventselect.cpp ws2_32.lib
    //
    // Command Line Options:
    //
    //    eventselect.exe 
    //
    //    Note: There are no command line options for this sample.#include <winsock2.h>
    #include <windows.h>
    #include <stdio.h>#define PORT 5150
    #define DATA_BUFSIZE 8192typedef struct _SOCKET_INFORMATION {
       CHAR Buffer[DATA_BUFSIZE];
       WSABUF DataBuf;
       SOCKET Socket;
       DWORD BytesSEND;
       DWORD BytesRECV;
    } SOCKET_INFORMATION, * LPSOCKET_INFORMATION;BOOL CreateSocketInformation(SOCKET s);
    void FreeSocketInformation(DWORD Event);DWORD EventTotal = 0;
    WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
    LPSOCKET_INFORMATION SocketArray[WSA_MAXIMUM_WAIT_EVENTS];void main(void)
    {
       SOCKET Listen;
       SOCKET Accept;
       SOCKADDR_IN InternetAddr;
       DWORD Event;
       WSANETWORKEVENTS NetworkEvents;
       WSADATA wsaData;
       DWORD Ret;
       DWORD Flags;
       DWORD RecvBytes;
       DWORD SendBytes;   if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
       {
          printf("WSAStartup() failed with error %d\n", Ret);
          return;
       }   if ((Listen = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
       {
          printf("socket() failed with error %d\n", WSAGetLastError());
          return;
       }    CreateSocketInformation(Listen);   if (WSAEventSelect(Listen, EventArray[EventTotal - 1], FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR)
       {
          printf("WSAEventSelect() failed with error %d\n", WSAGetLastError());
          return;
       }   InternetAddr.sin_family = AF_INET;
       InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
       InternetAddr.sin_port = htons(PORT);   if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
       {
          printf("bind() failed with error %d\n", WSAGetLastError());
          return;
       }   if (listen(Listen, 5))
       {
          printf("listen() failed with error %d\n", WSAGetLastError());
          return;
       }
             while(TRUE)
       {
          // Wait for one of the sockets to receive I/O notification and 
          if ((Event = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE,
             WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED)
          {
             printf("WSAWaitForMultipleEvents failed with error %d\n", WSAGetLastError());
             return;
          }
          if (WSAEnumNetworkEvents(SocketArray[Event - WSA_WAIT_EVENT_0]->Socket, EventArray[Event - 
             WSA_WAIT_EVENT_0], &NetworkEvents) == SOCKET_ERROR)
          {
             printf("WSAEnumNetworkEvents failed with error %d\n", WSAGetLastError());
             return;
          }      
          if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
          {
             if (NetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
             {
                printf("FD_ACCEPT failed with error %d\n", NetworkEvents.iErrorCode[FD_ACCEPT_BIT]);
                break;
             }         if ((Accept = accept(SocketArray[Event - WSA_WAIT_EVENT_0]->Socket, NULL, NULL)) == INVALID_SOCKET)
             {
                printf("accept() failed with error %d\n", WSAGetLastError());
                break;
             }         if (EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
             {
                printf("Too many connections - closing socket.\n");
                closesocket(Accept);
                break;
             }         CreateSocketInformation(Accept);         if (WSAEventSelect(Accept, EventArray[EventTotal - 1], FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR)
             {
                printf("WSAEventSelect() failed with error %d\n", WSAGetLastError());
                return;
             }         printf("Socket %d connected\n", Accept);
          }
      

  3.   

    // Try to read and write data to and from the data buffer if read and write events occur.      if (NetworkEvents.lNetworkEvents & FD_READ ||
             NetworkEvents.lNetworkEvents & FD_WRITE)
          {
             if (NetworkEvents.lNetworkEvents & FD_READ &&
                NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
             {
                printf("FD_READ failed with error %d\n", NetworkEvents.iErrorCode[FD_READ_BIT]);
                break;
             }         if (NetworkEvents.lNetworkEvents & FD_WRITE && 
                NetworkEvents.iErrorCode[FD_WRITE_BIT] != 0)
             {
                printf("FD_WRITE failed with error %d\n", NetworkEvents.iErrorCode[FD_WRITE_BIT]);
                break;
             }         LPSOCKET_INFORMATION SocketInfo = SocketArray[Event - WSA_WAIT_EVENT_0];         // Read data only if the receive buffer is empty.         if (SocketInfo->BytesRECV == 0)
             {
                SocketInfo->DataBuf.buf = SocketInfo->Buffer;
                SocketInfo->DataBuf.len = DATA_BUFSIZE;            Flags = 0;
                if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
                   &Flags, NULL, NULL) == SOCKET_ERROR)
                {
                   if (WSAGetLastError() != WSAEWOULDBLOCK)
                   {
                      printf("WSARecv() failed with error %d\n", WSAGetLastError());
                      FreeSocketInformation(Event - WSA_WAIT_EVENT_0);
                      return;
                   }
                } 
                else
                {
                   SocketInfo->BytesRECV = RecvBytes;
                }
             }         // Write buffer data if it is available.         if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)
             {
                SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
                SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;            if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
                   NULL, NULL) == SOCKET_ERROR)
                {
                   if (WSAGetLastError() != WSAEWOULDBLOCK)
                   {
                      printf("WSASend() failed with error %d\n", WSAGetLastError());
                      FreeSocketInformation(Event - WSA_WAIT_EVENT_0);
                      return;
                   }               // A WSAEWOULDBLOCK error has occured. An FD_WRITE event will be posted
                   // when more buffer space becomes available
                }
                else
                {
                   SocketInfo->BytesSEND += SendBytes;               if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
                   {
                      SocketInfo->BytesSEND = 0;
                      SocketInfo->BytesRECV = 0;
                   }
                }
             }
          }      if (NetworkEvents.lNetworkEvents & FD_CLOSE)
          {
             if (NetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
             {
                printf("FD_CLOSE failed with error %d\n", NetworkEvents.iErrorCode[FD_CLOSE_BIT]);
                break;
             }         printf("Closing socket information %d\n", SocketArray[Event - WSA_WAIT_EVENT_0]->Socket);         FreeSocketInformation(Event - WSA_WAIT_EVENT_0);
          }
       }
       return;
    }
    BOOL CreateSocketInformation(SOCKET s)
    {
       LPSOCKET_INFORMATION SI;
          
       if ((EventArray[EventTotal] = WSACreateEvent()) == WSA_INVALID_EVENT)
       {
          printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
          return FALSE;
       }   if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
          sizeof(SOCKET_INFORMATION))) == NULL)
       {
          printf("GlobalAlloc() failed with error %d\n", GetLastError());
          return FALSE;
       }   // Prepare SocketInfo structure for use.   SI->Socket = s;
       SI->BytesSEND = 0;
       SI->BytesRECV = 0;   SocketArray[EventTotal] = SI;   EventTotal++;   return(TRUE);
    }
    void FreeSocketInformation(DWORD Event)
    {
       LPSOCKET_INFORMATION SI = SocketArray[Event];
       DWORD i;   closesocket(SI->Socket);   GlobalFree(SI);   WSACloseEvent(EventArray[Event]);   // Squash the socket and event arrays   for (i = Event; i < EventTotal; i++)
       {
          EventArray[i] = EventArray[i + 1];
          SocketArray[i] = SocketArray[i + 1];
       }   EventTotal--;
    }
      

  4.   

    关注!因为我也是Socket新手。
    ----------------------------------------
    相信自己,相信明天!快给我分,不然我抢的啦^_^
    ----------------------------------------
                           时光.漫步
      

  5.   

    WSARecv返回0,表示操作正常,你可以检查WSARecv的第四个参数,该参数中存放的是接受到的字节数。
    如果有错误发生,可以通过调用WSAGetLastError()来获取具体的出错原因。
      

  6.   

    建议你参考一下《Windows网络编程》,有详细的例子和说明。