• Winsock Select模型范例


    服务器端:
    #include <Winsock2.h>
    #include <stdio.h>

    void InitSocket()
    {
     WORD wVersionRequested;
     WSADATA wsaData;
     int err;

     wVersionRequested = MAKEWORD( 2, 2 );

     err = WSAStartup( wVersionRequested, &wsaData );
     if ( err != 0 ) {
      /* Tell the user that we could not find a usable */
      /* WinSock DLL.                                  */
      return;
     }

     /* Confirm that the WinSock DLL supports 2.2.*/
     /* Note that if the DLL supports versions greater    */
     /* than 2.2 in addition to 2.2, it will still return */
     /* 2.2 in wVersion since that is the version we      */
     /* requested.                                        */

     if ( LOBYTE( wsaData.wVersion ) != 2 ||
      HIBYTE( wsaData.wVersion ) != 2 ) {
       /* Tell the user that we could not find a usable */
       /* WinSock DLL.                                  */
       WSACleanup( );
       return;
      }
    }
    int main(int argc, char* argv[])
    {
     InitSocket();
     SOCKET sock=::socket(AF_INET,SOCK_STREAM,0);
     if(sock==INVALID_SOCKET)
     {
      printf("创建socket失败");
      WSACleanup( );
      return 0;
     }
     //::sockaddr_in serAddr;
     SOCKADDR_IN serAddr;
     serAddr.sin_family=AF_INET;
     serAddr.sin_port=::htons(5150);
     serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
     if(SOCKET_ERROR==bind(sock,(sockaddr*)&serAddr,sizeof(sockaddr)))
     {
      printf("绑定失败");
      WSACleanup( );
      return 0;
     }
     listen(sock,5);
     fd_set fdSocket;
     FD_ZERO(&fdSocket);
     FD_SET(sock,&fdSocket);
     while(true)
     {
      fd_set fdRead=fdSocket;
      int nRet=::select(0,&fdRead,NULL,NULL,NULL);
      if(nRet>0)
      {
       for(int i=0;i<(int)fdSocket.fd_count;i++)
       {
        if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
        {
         //有新的连接到达
         if(fdSocket.fd_array[i]==sock)
         {
          if(fdSocket.fd_count<FD_SETSIZE)
          {
           ::sockaddr_in addr;
           int len=sizeof(sockaddr);
           SOCKET client=accept(sock,(sockaddr*)&addr,&len);
           printf("接收到新的连接 : %s/n",::inet_ntoa(addr.sin_addr));
           FD_SET(client,&fdSocket);
          }
          else
          {
           printf("too many connections/n");
          }
         }
         else
         {
          char*buf=new char[1024];
          int nRecv=::recv(fdSocket.fd_array[i],buf,1024,0);
          if(nRecv>0)
          {
           buf[nRecv]='/0';
           printf("收到数据: %s/n",buf);
          }
          else
          {
           ::closesocket(fdSocket.fd_array[i]);
           FD_CLR(fdSocket.fd_array[i],&fdSocket);
           printf("一客户端断开连接/n");
          }
          delete []buf;
         }
        }
       }
      }
     }
     return 0;
    }

    客户端:

    #include <winsock2.h>
    #include <stdio.h>
    #include <memory.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;
    }

  • 相关阅读:
    Tomcat、Jetty、Undertow、Netty 等容器的区别
    Spring boot整合Swagger2接口文档使用
    为项目配置了Bean,结果Spring Boot并没有扫描到
    yum安装软件所在目录的查询
    LINUX云服务器 安装 nginx
    Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm Lorg/gradle/api/artifacts/ModuleIdentifier;
    redis数据结构
    linux安装redis
    eclipse项目目录展示结构设置
    tomcat 搭建以及发布配置
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6168003.html
Copyright © 2020-2023  润新知