На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (4) « Первая ... 2 3 [4]  все  ( Перейти к последнему сообщению )  
> gcc - установка и настройка
    Цитата Qraizer @
    Совершенно несложно учесть разницу в конструкторах объектов-сокетах. Делов-то на один API-вызов. Но не сокетами ж едиными. Есть ещё файлы в $TEMP (...я бы так и вообще намутил basic_socketstream<> и натравил на std::​(i|o|io)stream), eсть готовые библиотеки, если религия заказчик не возражает.

    Можно вполне и так. Если не учесть, что ранее macomics пацанов туманил относительно MSYS2 :lol:

    Цитата macomics @
    Затем, что по заданию она должна компилироваться на linux. И вот тут косяк, если из-за как-то не учтенной особенности linux, не выученной своевременно, программа просто не сможет откомпилироваться.

    Вот элементарный пример. Для взаимодействия предложили использовать socket. Но на Windows для работы с socket надо использовать WSAStartup и WSACleanup, которых нету в linux. Т.е. с виду работоспособный код для Windows под linux просто выдаст ошибку отсутствия функций.

    Действительно, разная реализация сокетов в Windows и Linux имеет место. Но, что касаемо MSYS2, то лучше сперва прокачать вопрос, а потом утверждать. Дело в том, что перечисленные мною выше тулчейны не смогут собрать код для Linux-сокетов, просто не найдут Linux-специфических заголовков. Но все же MSYS2 - эмулятор Linux и у него кроме mingw-w64-* есть еще свой тулчейн /msys. Приведу пример, топикстартеру, уверен, пригодится ...

    Сперва установим необходимое

    ExpandedWrap disabled
      pacman -S msys/gcc
      pacman -S msys/gcc-libs
      pacman -S msys/binutils
      pacman -S msys/cmake
      pacman -S msys/ninja

    Да, при установке некоторые пакеты могут быть поставлены как зависимости к ранее поставленным пакетам, в этом случае можно повторно не ставить. К примеру установка /msys/gcc может подтянуть сразу /msys/gcc-libs и /msys/binutils. Я уже не помню, но что-то такое было. Не суть.

    Тестируем "родной" тулчейн

    По уже знакомому сценарию делаем проект, пусть в каталоге ~/dev/projects/echo-test, туда кладем файлы:

    server.cpp

    ExpandedWrap disabled
      #include <iostream>
      #include <cstring>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <unistd.h>
       
      int main() {
          int server_fd, new_socket, valread;
          struct sockaddr_in address;
          int opt = 1;
          int addrlen = sizeof(address);
          char buffer[1024] = {0};
          const char *hello = "Hello from server";
       
           if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
              perror("socket failed");
              exit(EXIT_FAILURE);
          }
       
           if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
              perror("setsockopt");
              exit(EXIT_FAILURE);
          }
          address.sin_family = AF_INET;
          address.sin_addr.s_addr = INADDR_ANY;
          address.sin_port = htons(8080);
       
           if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
              perror("bind failed");
              exit(EXIT_FAILURE);
          }
          if (listen(server_fd, 3) < 0) {
              perror("listen");
              exit(EXIT_FAILURE);
          }
          if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
              perror("accept");
              exit(EXIT_FAILURE);
          }
          valread = read(new_socket, buffer, 1024);
          printf("%s\n", buffer);
          send(new_socket, hello, strlen(hello), 0);
          printf("Hello message sent\n");
          return 0;
      }

    client.cpp

    ExpandedWrap disabled
      #include <iostream>
      #include <cstring>
      #include <sys/socket.h>
      #include <arpa/inet.h>
      #include <unistd.h>
       
      int main() {
          int sock = 0, valread;
          struct sockaddr_in serv_addr;
          const char *hello = "Hello from client";
          char buffer[1024] = {0};
          if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
              std::cerr << "\n Socket creation error \n";
              return -1;
          }
          serv_addr.sin_family = AF_INET;
          serv_addr.sin_port = htons(8080);
          if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
              std::cerr << "\nInvalid address/ Address not supported \n";
              return -1;
          }
          if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
              std::cerr << "\nConnection Failed \n";
              return -1;
          }
          send(sock, hello, strlen(hello), 0);
          std::cout << "Hello message sent\n";
          valread = read(sock, buffer, 1024);
          std::cout << buffer << std::endl;
          return 0;
      }

    CMakeLists.txt

    ExpandedWrap disabled
      cmake_minimum_required(VERSION 3.0)
      project(TestThreads)
       
      set(CMAKE_CXX_STANDARD 11)
      set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
       
      add_executable(server server.cpp)
      add_executable(client client.cpp)

    build.sh

    ExpandedWrap disabled
      #!/usr/bin/sh
       
      mkdir build
      cd build
      cmake -G Ninja ..
      ninja

    Запускаем сборку. Следует заметить, что в пакетном файле переменную окружения PATH мы не модифицируем. Тем самым запускается "родная" версия cmake, которая также ищет "родные" компиляторы и бинутилсы, которые располагаются непосредственно в /usr/bin. После сборки получаем два исполняемых файла формата PE (виндовых). Однако, хоть и проект был собран статически, одна динамическая зависимость осталась. Для работы исполняемым файлам нужно положить рядом msys-2.0.dll (его можно взять из /usr/bin).

    Запускаем сперва server.exe - программа висит и ждёт. Запускаем во втором окне client.exe. Обе программы завершают свою работу. При этом в окне sever.exe видим вывод:

    ExpandedWrap disabled
      Hello from client
      Hello message sent

    А в окне client.exe:

    ExpandedWrap disabled
      Hello message sent
      Hello from server

    Вот, собственно, такими нехитрыми манипуляциями мы собрали Linux-специфичный проект, и запустили его под M$ Windows :thanks:
      Цитата Majestio @
      Но все же MSYS2 - эмулятор Linux и у него кроме mingw-w64-* есть еще свой тулчейн /msys.

      Thanks за пример, даже не верится, что под винду заработает без WSAxxxx. В целом, то же самое, что я уже делал неоднократно, вот например из последнего: https://github.com/MrDemonid/Sync-time-from-NTP

      Но тогда уж вопрос на засыпку. У меня все попытки установить MSYS2 провалились, скорее всего из-за ошибок установки. И сейчас у меня просто minGW, в которой нет даже намёка на MSYS, то есть тупо вообще нет соответствующей консоли, так что ничего доставить не могу. И как быть? Ставить заново MSYS2? Так то я не против попробовать снова, но что делать с текущим minGW?
      Сейчас прошелся поиском и не нашел в папке minGW ключевых инклюдов:
      inet.h и socket.h
      так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади :(
        MSYS2 вроде заработал, всего одна ошибка при установке. Проект компилируется, правда только из терминала, VSCode поломался и ни в какую не создаёт нормальные json файлы. Подружить бы его с makefile для cmake, но пока итак пойдёт.
        Осталось только доделать.
        Всем спасибо за помощь и советы!
          Цитата Eretic @
          Так то я не против попробовать снова, но что делать с текущим minGW?

          Это вопрос тем, кто посоветовал :jokingly:
            Цитата Eretic @
            Сейчас прошелся поиском и не нашел в папке minGW ключевых инклюдов:
            inet.h и socket.h

            А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ?
            Вариант поиска:
            Во всех файлах *.h ищем ключевое слово "socket".

            Добавлено
            Цитата Eretic @
            так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади :(

            Сложности только начинаются.
            Поскольку кроме поставленной задачи, ты начал решать
            ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее.
            Наверняка будет много сюрпризов. Обычный из них - всё было хорошо и правильно для Виндуса.
            При попытке собрать приложение плд Линуксом исходники просто не компилируются.
            Сообщение отредактировано: ЫукпШ -
              Цитата ЫукпШ @
              А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ?

              Есть. Но это вариант виндозный и немного не то. Хотя на нём конечно получилось бы намного красивее и проще, чем сейчас замучиваю с select() :)
              Цитата ЫукпШ @
              Поскольку кроме поставленной задачи, ты начал решать
              ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее.

              Меня больше пугают установки неизвестных доселе пакетов, структуры которых я не понимаю. Теперь вот более-менее разобрался. О кроссплатформенности мне пока рано думать. Я же в качестве студента на каникулы заявку подал. Вряд ли кто-то ожидает, что бестолковый студент сразу начнет решать сложнейшие задачи, вызывающие головную боль даже у профессионалов :)
              А программки заработали. Единственный косяк - это забыл что в первый параметр select() нужно передавать значение на 1 больше сокета (максимального из набора) и почти час не мог понять - отчего постоянно выходит только по таймауту. Да, функция допотопная, но зато совместимость 100% и задаче отвечает полностью (приложения не должны зависеть друг от друга, а продолжать спокойно работу в случае закрытия одного их них) :)

              Добавлено
              Цитата ЫукпШ @
              При попытке собрать приложение плд Линуксом исходники просто не компилируются.

              Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так?
                Цитата Eretic @
                Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так?

                Все просто. Нужно просто прочесть расшифровку MinGW - Minimalist GNU for Windows. Там нет и не может быть заголовочных файлов для Linux, т.к. это инструмент заточен именно для Windows.
                  Цитата Majestio @
                  ужно просто прочесть расшифровку MinGW - Minimalist GNU for Windows.

                  Так я сейчас перешел с minGW на MSYS2.
                  К тому же из инклюдов у меня только:
                  #include <iostream>
                  #include <thread>
                  #include <algorithm>
                  #include <list>
                  #include <condition_variable>
                  #include <mutex>
                  #include <chrono>
                  #include <sys/socket.h>
                  #include <sys/select.h>
                  #include <arpa/inet.h>
                  #include <unistd.h>

                  Вроде ничего специфического, чисто плюсовые примочки, которые должны быть реализованы под любую платформу. Разве нет?
                    Цитата Eretic @
                    которые должны быть реализованы под любую платформу. Разве нет?

                    Чтобы код был кроссплатформенным, нужно примерно следующее:

                    ExpandedWrap disabled
                      #ifdef _WIN32
                          // Заголовки для Windows с использованием MinGW-w64
                          #include <winsock2.h>
                          #include <ws2tcpip.h>
                          #pragma comment(lib, "ws2_32.lib")
                      #else
                          // Заголовки для Linux
                          #include <sys/socket.h>
                          #include <arpa/inet.h>
                          #include <netinet/in.h>
                          #include <unistd.h>
                      #endif

                    Тулчейн /mingw32 будет использовать первую часть (виндовую), а /msys будет использовать вторую часть (линуховую). Соответственно, и в дальнейшей реализации нужно писать отдельные части для виндовс и линух, помещая их в блоки #ifdef. В стандарте С++ нет унифицированной работы с TCP/IP, поэтому указанные выше заголовки - платформозависимые.
                      Цитата Majestio @
                      #ifdef _WIN32
                          // Заголовки для Windows с использованием MinGW-w64
                         #include <winsock2.h>
                         #include <ws2tcpip.h>
                         #pragma comment(lib, "ws2_32.lib")

                      А зачем мне winsock, если у меня и без него всё работает? Говорю же, у меня подключено как раз вот это:
                      Цитата Majestio @
                      #else
                          // Заголовки для Linux
                         #include <sys/socket.h>
                         #include <arpa/inet.h>
                         #include <netinet/in.h>
                         #include <unistd.h>
                      #endif

                      И прекрасно работает под виндой. Еще разберусь, почему клиент не опознаёт потерю связи и можно сдать задание. С другой стороны, не распознает и фиг с ней, всё равно данные будут потеряны (в задаче нет ни слова о их хранении до восстановления связи).

                      Но в принципе можно проверить. Если есть желающий попробовать компильнуть под линуксом и проверить в работе, то пишите. Как только закончу - вышлю :) Заодно и узнаем, можно ли обойтись без #ifdef.
                        Цитата Eretic @
                        А зачем мне winsock, если у меня и без него всё работает? Говорю же, у меня подключено как раз вот это:

                        А потому, что дальше у тебя возникнет желание использовать WinAPI, а с "линуксовым" тулчейном тебя поприветствует облом. Нет в нем поддержки Windows, только ограниченная эмуляция (трансляция) линуховых вызовов в виндовые.
                          Ну как, найдётся желающий протестировать под линуксом?
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0526 ]   [ 18 queries used ]   [ Generated: 27.04.24, 07:01 GMT ]