Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.141.41.187] |
|
Страницы: (4) « Первая ... 2 3 [4] все ( Перейти к последнему сообщению ) |
Сообщ.
#46
,
|
|
|
Цитата Qraizer @ Совершенно несложно учесть разницу в конструкторах объектов-сокетах. Делов-то на один API-вызов. Но не сокетами ж едиными. Есть ещё файлы в $TEMP (...я бы так и вообще намутил basic_socketstream<> и натравил на std::(i|o|io)stream), eсть готовые библиотеки, если религия заказчик не возражает. Можно вполне и так. Если не учесть, что ранее macomics пацанов туманил относительно MSYS2 Цитата macomics @ Затем, что по заданию она должна компилироваться на linux. И вот тут косяк, если из-за как-то не учтенной особенности linux, не выученной своевременно, программа просто не сможет откомпилироваться. Вот элементарный пример. Для взаимодействия предложили использовать socket. Но на Windows для работы с socket надо использовать WSAStartup и WSACleanup, которых нету в linux. Т.е. с виду работоспособный код для Windows под linux просто выдаст ошибку отсутствия функций. Действительно, разная реализация сокетов в Windows и Linux имеет место. Но, что касаемо MSYS2, то лучше сперва прокачать вопрос, а потом утверждать. Дело в том, что перечисленные мною выше тулчейны не смогут собрать код для Linux-сокетов, просто не найдут Linux-специфических заголовков. Но все же MSYS2 - эмулятор Linux и у него кроме mingw-w64-* есть еще свой тулчейн /msys. Приведу пример, топикстартеру, уверен, пригодится ... Сперва установим необходимое 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 #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 #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 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 #!/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 видим вывод: Hello from client Hello message sent А в окне client.exe: Hello message sent Hello from server Вот, собственно, такими нехитрыми манипуляциями мы собрали Linux-специфичный проект, и запустили его под M$ Windows |
Сообщ.
#47
,
|
|
|
Цитата 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 так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади |
Сообщ.
#48
,
|
|
|
MSYS2 вроде заработал, всего одна ошибка при установке. Проект компилируется, правда только из терминала, VSCode поломался и ни в какую не создаёт нормальные json файлы. Подружить бы его с makefile для cmake, но пока итак пойдёт.
Осталось только доделать. Всем спасибо за помощь и советы! |
Сообщ.
#49
,
|
|
|
Цитата Eretic @ Так то я не против попробовать снова, но что делать с текущим minGW? Это вопрос тем, кто посоветовал |
Сообщ.
#50
,
|
|
|
Цитата Eretic @ Сейчас прошелся поиском и не нашел в папке minGW ключевых инклюдов: inet.h и socket.h А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ? Вариант поиска: Во всех файлах *.h ищем ключевое слово "socket". Добавлено Цитата Eretic @ так что по любому что-то делать нужно. А я то наивно думал, что самое сложное позади Сложности только начинаются. Поскольку кроме поставленной задачи, ты начал решать ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее. Наверняка будет много сюрпризов. Обычный из них - всё было хорошо и правильно для Виндуса. При попытке собрать приложение плд Линуксом исходники просто не компилируются. |
Сообщ.
#51
,
|
|
|
Цитата ЫукпШ @ А нет ли там файлов "windows.h", "winsock.h", "winsock2.h", "wininet.h" ? Есть. Но это вариант виндозный и немного не то. Хотя на нём конечно получилось бы намного красивее и проще, чем сейчас замучиваю с select() Цитата ЫукпШ @ Поскольку кроме поставленной задачи, ты начал решать ещё одну задачу - "кросплатформенность". Ещё не известно, что сложнее. Меня больше пугают установки неизвестных доселе пакетов, структуры которых я не понимаю. Теперь вот более-менее разобрался. О кроссплатформенности мне пока рано думать. Я же в качестве студента на каникулы заявку подал. Вряд ли кто-то ожидает, что бестолковый студент сразу начнет решать сложнейшие задачи, вызывающие головную боль даже у профессионалов А программки заработали. Единственный косяк - это забыл что в первый параметр select() нужно передавать значение на 1 больше сокета (максимального из набора) и почти час не мог понять - отчего постоянно выходит только по таймауту. Да, функция допотопная, но зато совместимость 100% и задаче отвечает полностью (приложения не должны зависеть друг от друга, а продолжать спокойно работу в случае закрытия одного их них) Добавлено Цитата ЫукпШ @ При попытке собрать приложение плд Линуксом исходники просто не компилируются. Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так? |
Сообщ.
#52
,
|
|
|
Цитата Eretic @ Но ведь я компилирую gcc? То есть тем самым компилятором, что является основным в линуксе. Что тут может пойти не так? Все просто. Нужно просто прочесть расшифровку MinGW - Minimalist GNU for Windows. Там нет и не может быть заголовочных файлов для Linux, т.к. это инструмент заточен именно для Windows. |
Сообщ.
#53
,
|
|
|
Цитата 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> Вроде ничего специфического, чисто плюсовые примочки, которые должны быть реализованы под любую платформу. Разве нет? |
Сообщ.
#54
,
|
|
|
Цитата Eretic @ которые должны быть реализованы под любую платформу. Разве нет? Чтобы код был кроссплатформенным, нужно примерно следующее: #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, поэтому указанные выше заголовки - платформозависимые. |
Сообщ.
#55
,
|
|
|
Цитата 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. |
Сообщ.
#56
,
|
|
|
Цитата Eretic @ А зачем мне winsock, если у меня и без него всё работает? Говорю же, у меня подключено как раз вот это: А потому, что дальше у тебя возникнет желание использовать WinAPI, а с "линуксовым" тулчейном тебя поприветствует облом. Нет в нем поддержки Windows, только ограниченная эмуляция (трансляция) линуховых вызовов в виндовые. |
Сообщ.
#57
,
|
|
|
Ну как, найдётся желающий протестировать под линуксом?
|