1. C++ / Говнокод #14526

    +63

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    int main()
    {
    	server::CServer();
    	return 0;
    }
    
    class CServer {
    public:
        CServer()
        {
            SOCKET listen_sd = socket (AF_INET, SOCK_STREAM, 0);	  CHK_ERR(listen_sd, "socket");
            SET_NONBLOCK(listen_sd);
    
            struct sockaddr_in sa_serv;
            memset (&sa_serv, '\0', sizeof(sa_serv));
            sa_serv.sin_family      = AF_INET;
            sa_serv.sin_addr.s_addr = INADDR_ANY;
            sa_serv.sin_port        = htons (1111);          /* Server Port number */
    
            int err = ::bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv));      CHK_ERR(err, "bind");
            
            err = listen (listen_sd, 5);            CHK_ERR(err, "listen");
    
            while(true)
            {
                    Sleep(1);
    
                    struct sockaddr_in sa_cli;  
                    size_t client_len = sizeof(sa_cli);
    #ifdef WIN32
                    const SOCKET sd = accept (listen_sd, (struct sockaddr*) &sa_cli, (int *)&client_len);
    #else
                    const SOCKET sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
    #endif  
                    Callback(sd);
            }
        }
    };

    http://habrahabr.ru/post/211853/

    Бесконечный цикл (event loop) в конструкторе.

    Опущены неинтересные строчки инициализации всякой фигни.

    Про Sleep вместо select/epoll/etc. я вовсе молчу.

    Запостил: WGH, 08 Февраля 2014

    Комментарии (7) RSS

    • Кто-нибудь пояснит смысл приведения к int* в строке 31?
      Ответить
      • Ну а что там пояснять, на винде accept принимает int* третьим аргументом. size_t* не приводится к int* по-хорошему, вот автор и приводит по-плохому. Не помню, что там говорит стандарт на этот счет, но теоретически может случиться страшная фигня.

        На практике, если sizeof(int) == sizeof(size_t), то код будет нормально работать, пока размер адреса не превысит, например, двух гигабайт (при 32-битном). Что маловероятно.

        Если size_t шире (как на x86_64), то тут уже интереснее. На little-endian машинах работать будет, а на big-endian уже нет.
        Ответить
        • То есть программа работает на вин32 как положено, а на остальных системах как повезёт? (в зависимости от типа который принимает accept/особенностей платформы)

          А какой смысл а) брать указатель на переменную, которая по логике не должна менятся, б) использовать знаковое значение под длину. Тут говно похоже не только в коде из топика.

          + Если делать условную компиляцию под разные платформы, то в else ветке должно быть исключительно static_assert(false, "Unsupported platform")
          Ответить
          • Только на винде там int*. На нормальных системах третий аргумент - socklen_t*. Так что да, у MS тоже говно. А ещё автору вновь повезло, что socklen_t совпал с size_t на не-виндах.

            >а на остальных системах как повезёт?
            Если там окажется тип, несовместимый с size_t*, то код тупо не скомпилится. Это только на винде автор устроил лотерею жестким кастом.

            А переменная на самом деле меняется. Туда записывается, сколько именно байт было использовано под адрес.
            Ответить
    • Обратили внимание на ::bind? Всё верно, просто автор выше по коду додумался написать using namespace std.
      Ответить
    • Лол, в трех статьях одна ссылка на asio. И вообще:
      std::vector<unsigned char> vBuffer(4096); //выделяем буфер для входных данных
      memset(&vBuffer[0], 0, vBuffer.size()); //заполняем буфер нулями
      // ...
      const std::string strHTML = /*...*/;
      std::ostringstream strStream;
      strStream << /*...*/ << strHTML.c_str();
      // ...
      while(nCurrentPos < strStream.str().length())
      // ...
      struct sockaddr_in sa_serv;
      memset (&sa_serv, '\0', sizeof(sa_serv));
      Ответить
    • нахуя тут вообще класс? жабоёб писал?
      Ответить

    Добавить комментарий