Кресты / Говнокод #14526 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 WGH, (Updated )

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

    • Ну а что там пояснять, на винде 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));
    Ответить

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

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8