其实在MSDN中就有,两个聊天程序,客户端和服务端,如果需要别的例程,也可以,我有一个例程。要的话给我EMAIL:[email protected]

解决方案 »

  1.   

    异步有很多模式,你到底要哪种!是关于select 的例子吗,或是wsaasyncselect的例子,或是
    大规模i/o例子等等,请详细一点?需要哪一种后,我给你email过去
      

  2.   

    到VCHELP。NET去看看吧,有源程序。
      

  3.   

    是wsaasyncselect的例子,vchelp好象没有太合适的。
      

  4.   

    我也想看看
    我都要 
    [email protected]
    謝謝
      

  5.   

    如果你用MFC做SOCKET很简单,CSOCKT类是同步的,也是阻塞的。要做非阻塞的,用 CAsyncSocket类。这是一个非阻塞的异步通讯类,比CSOCKT低级。中间注意的是:因为是非阻塞的,它执行中有很多返回。所以,当返回是SOCKET_ERROR时,要判断ERROR的值。用GetLastError(),如果是WSAEWOULDBLOCK的话,不是有错,而是发生阻塞,你可以及时处理,如重发、忽略。其中CONNECT是需要忽略的。
    方法很简单,不要看例子,自己做吧。
    服务端:
      1:声明两个SOCKET对象:LISTENSOCKET 、WORKSOCKET
      2:监听用LISTENSOCKET
      3:ACCEPT (WORKSOCKET)
      4:RECEIVE、SEND
    客户端:
      1:声明1个SOCKET
      2:CONNECT(HOST)若SOCKET——ERROR此时判断是否WSAEWOULDBLOCK
      3:RECEIVE、SEND
    要是想在ONSEND、ONRECEIVE、ONACCEPT等触发函数间切换,可用AsyncSelect(FD_READ\FD_WRITE\FD_ACCEPT)等;。
    别忘了加分哦!
      
      

  6.   

    我要看使用 API的,我不用MFC呀,你们有吗?
      

  7.   

    // Module Name: asyncselect.cpp
    //
    // Description:
    //
    //    This sample illustrates how to develop a simple echo server Winsock
    //    application using the WSAAsyncSelect() I/O model. This sample is
    //    implemented as a console-style application (to reduce the programming
    //    complexity of writing a real Windows 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.
    //
    //    Since the WSAAsyncSelect I/O model requires an application to manage
    //    window messages when network event occur, this application creates
    //    a window for the I/O model only. The window stays hidden during the
    //    entire execution of this application.
    //
    // Compile:
    //
    //    cl -o asyncselect asyncselect.cpp ws2_32.lib user32.lib gdi32.lib
    //
    // Command Line Options:
    //
    //    asyncselect.exe 
    //
    //    Note: There are no command line options for this sample.#include <winsock2.h>
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>#define PORT 5150
    #define DATA_BUFSIZE 8192typedef struct _SOCKET_INFORMATION {
       BOOL RecvPosted;
       CHAR Buffer[DATA_BUFSIZE];
       WSABUF DataBuf;
       SOCKET Socket;
       DWORD BytesSEND;
       DWORD BytesRECV;
       _SOCKET_INFORMATION *Next;
    } SOCKET_INFORMATION, * LPSOCKET_INFORMATION;#define WM_SOCKET (WM_USER + 1)void CreateSocketInformation(SOCKET s);
    LPSOCKET_INFORMATION GetSocketInformation(SOCKET s);
    void FreeSocketInformation(SOCKET s);HWND MakeWorkerWindow(void);
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);LPSOCKET_INFORMATION SocketInfoList;void main(void)
    {
       MSG msg;
       DWORD Ret;
       SOCKET Listen;
       SOCKADDR_IN InternetAddr;
       HWND Window;
       WSADATA wsaData;   if ((Window = MakeWorkerWindow()) == NULL)
          return;   // Prepare echo server   if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
       {
          printf("WSAStartup failed with error %d\n", Ret);
          return;
       }   if ((Listen = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
       {
          printf("socket() failed with error %d\n", WSAGetLastError());
          return;
       }    WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT|FD_CLOSE);   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;
       }
         
       // Translate and dispatch window messages for the application thread   while(Ret = GetMessage(&msg, NULL, 0, 0))
       {
          if (Ret == -1)
          {
             printf("GetMessage() failed with error %d\n", GetLastError());
             return;
          }      TranslateMessage(&msg);
          DispatchMessage(&msg);
       }
    }
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
       SOCKET Accept;
       LPSOCKET_INFORMATION SocketInfo;
       DWORD RecvBytes, SendBytes;
       DWORD Flags;   if (uMsg == WM_SOCKET)
       {
          if (WSAGETSELECTERROR(lParam))
          {
             printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
             FreeSocketInformation(wParam);
          } 
          else
          {
             switch(WSAGETSELECTEVENT(lParam))
             {
                case FD_ACCEPT:               if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)
                   {
                      printf("accept() failed with error %d\n", WSAGetLastError());
                      break;
                   }               // Create a socket information structure to associate with the
                   // socket for processing I/O.               CreateSocketInformation(Accept);               printf("Socket number %d connected\n", Accept);               WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);               break;            case FD_READ:               SocketInfo = GetSocketInformation(wParam);               // Read data only if the receive buffer is empty.               if (SocketInfo->BytesRECV != 0)
                   {
                      SocketInfo->RecvPosted = TRUE;
                      return 0;
                   }
                   else
                   {
                      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(wParam);
                            return 0;
                         }
                      } 
                      else // No error so update the byte count
                      {
                         SocketInfo->BytesRECV = RecvBytes;
                      }
                   }               // DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead
                   // and begin writing data to the client.            case FD_WRITE:                   SocketInfo = GetSocketInformation(wParam);               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(wParam);
                            return 0;
                         }
                      } 
                      else // No error so update the byte count
                      {
                         SocketInfo->BytesSEND += SendBytes;
                      }
                   }               if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
                   {
                      SocketInfo->BytesSEND = 0;
                      SocketInfo->BytesRECV = 0;                  // If a RECV occurred during our SENDs then we need to post an FD_READ
                      // notification on the socket.                  if (SocketInfo->RecvPosted == TRUE)
                      {
                         SocketInfo->RecvPosted = FALSE;
                         PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
                      }
                   }               break;            case FD_CLOSE:               printf("Closing socket %d\n", wParam);
                   FreeSocketInformation(wParam);               break;
             }
          }
          return 0;
       }   return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    void CreateSocketInformation(SOCKET s)
    {
       LPSOCKET_INFORMATION SI;   if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
          sizeof(SOCKET_INFORMATION))) == NULL)
       {
          printf("GlobalAlloc() failed with error %d\n", GetLastError());
          return;
       }   // Prepare SocketInfo structure for use.   SI->Socket = s;
       SI->RecvPosted = FALSE;
       SI->BytesSEND = 0;
       SI->BytesRECV = 0;   SI->Next = SocketInfoList;   SocketInfoList = SI;
    }LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)
    {
       SOCKET_INFORMATION *SI = SocketInfoList;   while(SI)
       {
          if (SI->Socket == s)
             return SI;      SI = SI->Next;
       }   return NULL;
    }void FreeSocketInformation(SOCKET s)
    {
       SOCKET_INFORMATION *SI = SocketInfoList;
       SOCKET_INFORMATION *PrevSI = NULL;   while(SI)
       {
          if (SI->Socket == s)
          {
             if (PrevSI)
                PrevSI->Next = SI->Next;
             else
                SocketInfoList = SI->Next;         closesocket(SI->Socket);
             GlobalFree(SI);
             return;
          }      PrevSI = SI;
          SI = SI->Next;
       }
    }HWND MakeWorkerWindow(void)
    {
       WNDCLASS wndclass;
       CHAR *ProviderClass = "AsyncSelect";
       HWND Window;   wndclass.style = CS_HREDRAW | CS_VREDRAW;
       wndclass.lpfnWndProc = (WNDPROC)WindowProc;
       wndclass.cbClsExtra = 0;
       wndclass.cbWndExtra = 0;
       wndclass.hInstance = NULL;
       wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
       wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
       wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
       wndclass.lpszMenuName = NULL;
       wndclass.lpszClassName = ProviderClass;   if (RegisterClass(&wndclass) == 0)
       {
          printf("RegisterClass() failed with error %d\n", GetLastError());
          return NULL;
       }   // Create a window.   if ((Window = CreateWindow(
          ProviderClass,
          "",
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          NULL,
          NULL,
          NULL,
          NULL)) == NULL)
       {
          printf("CreateWindow() failed with error %d\n", GetLastError());
          return NULL;
       }   return Window;
    }
      

  8.   

    l634youngpig: GetSocketInformation函数的参数类型是SOCKET还是WPARAM,为什么不一致。
    收到FD_READ消息时如何知道消息来源是哪个SOCKET?