• Winsock WSAEventSelect模型范例


    服务器端代码:

    #include <Winsock2.h>
    #include <iostream>
    #include <string>
    using namespace std;

    int main()
    {
     WORD wVersionRequested;
     WSADATA wsaData;
     int err;
     char buffer[256];
     memset(buffer, 0, 256);

     wVersionRequested = MAKEWORD( 2, 2 );

     err = WSAStartup( wVersionRequested, &wsaData );
     if ( err != 0 )
     {
      return 1;
     }

     if ( LOBYTE( wsaData.wVersion ) != 2 ||
      HIBYTE( wsaData.wVersion ) != 2 )
     {
      WSACleanup( );
      return 1;
     }

     SOCKET Sockets[WSA_MAXIMUM_WAIT_EVENTS];
     WSAEVENT Event[WSA_MAXIMUM_WAIT_EVENTS];
     SOCKET Accept, Listen;
     DWORD EventTotal = 0;
     DWORD Index;

     Listen = socket(AF_INET, SOCK_STREAM, 0);
     WSAEVENT NewEvent;
     NewEvent = WSACreateEvent();
     WSAEventSelect(Listen, NewEvent, FD_ACCEPT|FD_CLOSE);

     char hostname[256];
     gethostname(hostname,sizeof(hostname));                      //这一代码是为
     hostent* hos=gethostbyname(hostname);                        //了实现自动获取安
     string CS=inet_ntoa(*(struct in_addr*)hos->h_addr_list[0]);  // 装程序的主机代码

     sockaddr_in saServer;
     saServer.sin_addr.S_un.S_addr = inet_addr(CS.c_str());//宏INADDR_ANY定义的是0
     saServer.sin_family = AF_INET;
     saServer.sin_port = htons(5150);
     bind(Listen, (SOCKADDR*)&saServer, sizeof(SOCKADDR));

     listen(Listen, 5);

     for(int i=0; i<WSA_MAXIMUM_WAIT_EVENTS; i++)
     {
      Sockets[i] = INVALID_SOCKET;
     }

     Sockets[EventTotal] = Listen;
     Event[EventTotal] = NewEvent;
     EventTotal++;

     WSANETWORKEVENTS NetworkEvent;

     while(1)
     {
      Index = WSAWaitForMultipleEvents(EventTotal, Event, FALSE, WSA_INFINITE, FALSE);
      WSAEnumNetworkEvents(Sockets[Index - WSA_WAIT_EVENT_0], Event[Index - WSA_WAIT_EVENT_0],
       &NetworkEvent);
      if(NetworkEvent.lNetworkEvents & FD_ACCEPT)
      {
       ::sockaddr_in addr;
       int len=sizeof(sockaddr);
       Accept = accept(Sockets[Index - WSA_WAIT_EVENT_0], (sockaddr*)&addr,&len);
       cout<<"接收到新的连接 :"<<::inet_ntoa(addr.sin_addr)<<endl;

       if(EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
       {
        closesocket(Accept);
        break;
       }
       NewEvent = WSACreateEvent();
       WSAEventSelect(Accept, NewEvent, FD_WRITE|FD_READ|FD_CLOSE);
       Sockets[EventTotal] = Accept;
       Event[EventTotal] = NewEvent;
       EventTotal++;
      }
      if(NetworkEvent.lNetworkEvents & FD_READ)
      {
       recv(Sockets[Index - WSA_WAIT_EVENT_0], buffer, sizeof(buffer), 0);
       cout<<buffer<<endl;
      }
      if(NetworkEvent.lNetworkEvents & FD_WRITE)
      {
       send(Sockets[Index - WSA_WAIT_EVENT_0], "this is a text", sizeof("this is a text"), 0);
      }
      if(NetworkEvent.lNetworkEvents & FD_CLOSE)
      {
       closesocket(Sockets[Index - WSA_WAIT_EVENT_0]);
       for(int j=Index - WSA_WAIT_EVENT_0; j<WSA_MAXIMUM_WAIT_EVENTS-1; j++)
       {
        Sockets[j] = Sockets[j+1];
        Event[j] = Event[j+1];
       }
       Sockets[WSA_MAXIMUM_WAIT_EVENTS-1] = INVALID_SOCKET;
       Event[WSA_MAXIMUM_WAIT_EVENTS-1] = WSA_INVALID_EVENT;
       EventTotal--;
      }
     }
    }

    客户端:

    #include <winsock2.h>
    #include <stdio.h>
    #include <iostream>
    #include <string>
    using namespace std;

    void main(int argc, char **argv)
    {
     WSADATA              wsaData;
     SOCKET               s;
     SOCKADDR_IN          ServerAddr;
     int                  Port = 5150;
     int                  Ret, Ret1;
     string Data;
     char     DataServe[8];
     memset(DataServe, 0, 8);
     char pause;

     if (argc <= 1)
     {
      printf("USAGE: tcpclient <Server IP address>./n");
      return;
     }

     // Initialize Winsock version 2.2

     if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
     {
      // NOTE: Since Winsock failed to load we cannot use WSAGetLastError
      // to determine the error code as is normally done when a Winsock
      // API fails. We have to report the return status of the function.

      printf("WSAStartup failed with error %d/n", Ret);
      return;
     }

     // Create a new socket to make a client connection.

     if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
      == INVALID_SOCKET)
     {
      printf("socket failed with error %d/n", WSAGetLastError());
      WSACleanup();
      return;
     }

     // Setup a SOCKADDR_IN structure that will be used to connect
     // to a listening server on port 5150. For demonstration
     // purposes, we required the user to supply an IP address
     // on the command line and we filled this field in with the
     // data from the user.

     ServerAddr.sin_family = AF_INET;
     ServerAddr.sin_port = htons(Port);   
     ServerAddr.sin_addr.s_addr = inet_addr(argv[1]);

     // Make a connection to the server with socket s.

     printf("We are trying to connect to %s:%d.../n",
      inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port));

     if (connect(s, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr))
      == SOCKET_ERROR)
     {
      printf("connect failed with error %d/n", WSAGetLastError());
      closesocket(s);
      WSACleanup();
      return;
     }

     printf("Our connection succeeded./n");

     // At this point you can start sending or receiving data on
     // the socket s. We will just send a hello message to the server.

     printf("We will now try to send a hello message./n");

     for(int i = 0; i<3; i++)
     {
      cin>>Data;
      if ((Ret = send(s, Data.c_str()/*"Hello"*/, Data.size(), 0)) == SOCKET_ERROR)
      {
       printf("send failed with error %d/n", WSAGetLastError());
       closesocket(s);
       WSACleanup();
       return;
      }
      printf("We successfully sent %d byte(s)./n", Ret);
     }

     // When you are finished sending and receiving data on socket s,
     // you should close the socket.

     printf("We are closing the connection./n");

     closesocket(s);

     // When your application is finished handling the connection, call
     // WSACleanup.

     WSACleanup();
     cin>>pause;
    }

  • 相关阅读:
    %和format的区别
    C++ 使用 curl 进行 http 请求(GET、POST、Download)的封装
    C++ log4cplus 类库的封装
    linux top 命令
    python使用urllib2 http 下载参数的try catch
    C 小白的 thrift 环境搭建
    pandas 必背函数操作
    flask + MySQL-python 创建 webapp 应用
    python 的 virtualenv 环境搭建及 sublime 手动创建运行环境
    nginx proxy_pass指令’/’注意事项
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6168002.html
Copyright © 2020-2023  润新知