Клиент-серверное приложение на языке Си (TCP, Linux)

  Рет қаралды 30,433

mxhpns: Программирование на Си от эксперта

mxhpns: Программирование на Си от эксперта

Күн бұрын

Напишем с вами клиент-серверное приложение на языке Си, работающее по протоколу TCP (Linux).
Исходный код: github.com/mxh...
Оставляйте свои вопросы в комментариях и желаемый материал

Пікірлер: 90
@lex.mikachev
@lex.mikachev 3 жыл бұрын
Это самое годное и интересное видео по сетевому программированию на C под Unix/Linux. Круто! Так держать!
@mxhpns7322
@mxhpns7322 3 жыл бұрын
пасиба
@vasilykovalev9644
@vasilykovalev9644 2 жыл бұрын
Респект чувак, с первых секунд понял тип контента и подписался. Получил эстетическое удовольствие от осознанной власти человеческого ума над машиной. Так держать)
@АлексейШутко
@АлексейШутко 3 жыл бұрын
Vim, терминал!!! Красота! Ничего лишнего! Превосходная подача материала!👍👍👍
@mxhpns7322
@mxhpns7322 3 жыл бұрын
спасибо!
@_CoDe_WiTh_Me_
@_CoDe_WiTh_Me_ 2 жыл бұрын
Спасибо за контент очень помогли разобраться в некоторых моментах! 👍👍👍
@eugenevladoff2758
@eugenevladoff2758 10 ай бұрын
Отлично, отлично! Спасибо за видео!
@user-wc6cd1ol3u
@user-wc6cd1ol3u 2 жыл бұрын
Большое спасибо, отличный канал, очень полезно. Побольше бы таких видео
@garbendRaff
@garbendRaff 4 жыл бұрын
Всё круто, продолжай!
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Спасибо большое!)
@davidflame7833
@davidflame7833 3 жыл бұрын
Спасибо, очень полезное видео, все наглядно и объяснено. Зрителям перед просмотром советую посмотреть статью вики Сокеты Беркли. Как раз сейчас подобная лаба в универе по Основам Информационной безопаности.
@mxhpns7322
@mxhpns7322 3 жыл бұрын
пасиб
@ancient-raccoon
@ancient-raccoon 3 жыл бұрын
Огромное спасибо за урок. сегодня понял 2 вещи: 1) я наконец понял что за конструкция #ifndef-#define-#endif; 2) работа с сетью не так сложна как кажется, особенно когда показывают на живом примере.
@miracles1282
@miracles1282 2 жыл бұрын
Смотрю в 2022. Спасибо за материал!
@recreationreally4382
@recreationreally4382 4 жыл бұрын
Все очень неплохо, даже вимчик перестал пугать и практически уложились в полпары.
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Так держать!)
@roduman
@roduman 2 жыл бұрын
Ты крут парень!!! Спасибо. Классный урок.
@timemanager3239
@timemanager3239 10 ай бұрын
Спасибо за контент очень помогли
@user-rt2yx2fe5n
@user-rt2yx2fe5n 2 жыл бұрын
Большое спасибо!
@rajahbtw
@rajahbtw Жыл бұрын
Очень приятно смотреть
@ommmirage
@ommmirage Жыл бұрын
Огромное спасибо за урок! Вопрос: в server.c: #include #include #include "erproc.h" B errproc.h: #include #include Мы ведь два раза включаем эти хедеры?
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Исходный код: github.com/mxhpns/client-server-linux-tcp
@anaraliyev214
@anaraliyev214 3 жыл бұрын
Будут ли серьёзные изменения данного исходного кода для Windows?
@mxhpns7322
@mxhpns7322 3 жыл бұрын
@@anaraliyev214 да, в windows используется winsock2. изменения значительные
@anaraliyev214
@anaraliyev214 3 жыл бұрын
@@mxhpns7322 надо будет разок попробовать вместе это проделать.
@mxhpns7322
@mxhpns7322 3 жыл бұрын
@@anaraliyev214 хорошая идея) у меня есть наработанные навыки в этой сфере) кстати с наступающим новым годом тебя
@anaraliyev214
@anaraliyev214 3 жыл бұрын
@@mxhpns7322 тогда сделаем это в один из выходных) с наступающим праздником и тебя! Всего наилучшего в 2021-ом году! :)
@user-lv7lv7fd1d
@user-lv7lv7fd1d 5 ай бұрын
глупый вопрос но все же... Этот клиент и сервер будет работать, если запустить на разных компах, подключенных к одной сети?
@dominuspiritus
@dominuspiritus 4 жыл бұрын
Спасибо за урок. Очень помогло
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Да, это видео у меня топовое) от студентов эта тема требуется крайне часто!) Я рад, что не зря создал это видео) помогаю людям в конце концов. Спасибо за комментарий!) если интересна графика на языке си, то посмотри следующий мой плейлист: kzbin.info/www/bejne/pne3kKaCas2KpZo
@MrRnwer
@MrRnwer 2 жыл бұрын
Я тут пару видосов посмотрел не до конца и психанул… челы в nano что-то пишут на сях ))) Жесть))) А здесь все норм)
@user-ly7cf9hh5x
@user-ly7cf9hh5x 7 ай бұрын
Здравствуйте! Отличная подача материала! Спасибо! Есть один вопрос: можно ли создать два сокета на прослушивание входящих соединений, но на разных портах? Я занимаюсь разработкой устройств с использованием GSM-модулей. То есть устройство (их может быть несколько) выступает в качестве клиента, и подключается на один порт сервера. И например управляющая программа для этих устройств, которая подключается на другой порт. А сам сервер уже перенаправляет запросы с программы на устройства и обратно, с устройств на программу.
@user-vl9kp6kk8w
@user-vl9kp6kk8w 4 жыл бұрын
Теперь знаю, что буду учить порядка следующих 5 лет - сетевое программирование. П. с Ухты, в виме можно табы делать 0_0
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Да, это очень круто)
@user-jg7oz8rj8n
@user-jg7oz8rj8n 4 жыл бұрын
Вы так сильно выручили!!! Спасибо вам огромное!
@mxhpns7322
@mxhpns7322 4 жыл бұрын
рад, что помог!)
@user-tt3yr3ow1n
@user-tt3yr3ow1n 4 жыл бұрын
@@mxhpns7322 а вы сможете написать код клента если код сервера уже есть?
@mxhpns7322
@mxhpns7322 4 жыл бұрын
@@user-tt3yr3ow1n Здравствуйте. Телеграм: @mxhpns (1200р/60мин)
@user-jc7gr9fc4s
@user-jc7gr9fc4s 4 жыл бұрын
лучший
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Благодарю!)
@YaVampiRchiG
@YaVampiRchiG 3 жыл бұрын
Здравствуйте! Наткнулась на ваше видео, очень понравилось, сейчас пишу проект webserv на c++. Хотела спросить, нет ли у вас продолжения? Или может быть вы сможете посоветовать какую-то литературу, чтобы написать вебсервер, который сможет обслуживать одновременно несколько клиентов? Могу скинуть сабжект по проекту. Спасибо!
@rajahbtw
@rajahbtw Жыл бұрын
Попахивает школой 21))))
@Iaroslav-up6bf
@Iaroslav-up6bf Жыл бұрын
42
@5665g
@5665g 4 жыл бұрын
Спасибо за урок. Есть вопросы: можно ли делать выход "exit(EXIT_FAILURE)", не закрыв сокеты? И есть ли разница, в случае приема данных от клиента, между recv(), принимающей дескриптор сокета в качестве аргумента, и read(), принимающей файловый дескриптор?
@mxhpns7322
@mxhpns7322 4 жыл бұрын
read() и recv() работает одинаково, но recv() не будет работать с файлами, только с сокетом, а read()-у нельзя передать дополнительные флаги, специфические для сокета (последний параметр recv()). Можно сделать выход, не закрыв сокеты, но в этом случае сокет может быть ещё несколько минут оставаться в системной таблице и другие серверные программы могут не смочь открыть тот же порт. В общем, желательно закрывать. На самом деле, там огромная теория, связанная с правильным закрытием TCP-сокетов, нюансов достаточно много
@BERENDEIJr
@BERENDEIJr 3 жыл бұрын
Добрый день! Такой вопрос: данный сервер ведь будет работать только в пределах локальной сети. Но, возможно ли объединить 2 удаленных компьютера в локальную сеть, например, через Hamachi ? Будет ли в таком случае полноценное соединение удаленных компьютеров?
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Сервер должен работать как в локальной сети, так и за её пределами, где пингуется этот сервер. Зависит от того, как подключён к Интернету компьютер, на котором запущен сервер. Насчёт Hamachi не знаю. Если компьютер подключен напрямую к кабелю, а также, если IP-адрес белый (статический - не меняется во времени), то к этому компу можно подключиться хоть с любого устройства в мире. Если подключен к роутеру, то на роутере желательно иметь белый IP-адрес и в настройках NAT задать проброс порта, который прослушивается, или задать, что твой комп самый крутой из всех подключенных к роутеру (это называется DMZ)
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Также, если комп-сервер подключен к роутеру, то любое устройство, подключенное к роутеру может получить доступ к серверу по IP-адресу, который выдало роутер компу-серверу. Узнать его можно с помощью команды ipconfig /all в windows или ifconfig -a на линуксе. Что касается доступа за пределами сети, то нужен ip-адрес роутера, как я написал в комментарии выше. Чтобы его узнать, можно зайти на сайт 2ip.ru. Он покажет текущий ip-шник
@Sergiy_83
@Sergiy_83 3 жыл бұрын
Как корректно закрыть сокеты? Если перезапустить сервер то получаю от bind : Address already in use. Не критично но при отладке (приходится часто перезапускать) приложения не могу подключится клиентом некоторое время? Спасибо.
@mxhpns7322
@mxhpns7322 3 жыл бұрын
нужно ловить сигнал ctrl+c с помощью sigaction и закрывать, но если нужно просто сдать лабу, то задай опцию so reuseaddr. Засчет этой опции во время bind'а, даже если порт ещё остаётся открытым, ошибки не будет
@mxhpns7322
@mxhpns7322 3 жыл бұрын
можешь ещё посмотреть комментарий Александра Новикова
@vveklenko
@vveklenko 3 жыл бұрын
Подскажите пожалуйста, это многопоточность или многопроцессорность?
@viktor_borodin
@viktor_borodin 3 жыл бұрын
Потоки это pthread, или std::thread. Многопроцессорность относится к железу. Потоки - сущность из программирования. Потоки насколько я знаю могут быть вообще не привязаны к определенному ядру. На одном ядре обычно обрабатывается несколько потоков. Не одновременно, насколько я понимаю, а по очереди. Один поток засыпает, просыпается другой и таким образом они делятся с друг другом процессорным временем, точнее процессор переключается между ними. В чем-то я могу быть не прав, так как имею в этом мало опыта. Посмотри simple code на youtube про многопоточность
@user-yn5zf3gp6k
@user-yn5zf3gp6k 4 жыл бұрын
Эффект залипшего порта так убирается? До функции Bind: int opt = 1; Setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
@mxhpns7322
@mxhpns7322 4 жыл бұрын
Да. Если при выключении программы, она явно по какой-то причине не указала, что порт нужно резко закрыть, то в зависимости от конфигурации ОС, данный порт (речь идёт исключительно о TCP-портах) остаётся открытым 1-5 минут. Это сделано, Т.к. TCP-протокол должен гарантировать доставку. Но по умолчанию, при попытке использовать порт (т.е. при биндинге), если порт пока считается открытым, неудаётся его задействовать, что особенно становится смешным (для преподавателей) при защите лаб на такую тему. Поэтому чтобы избежать такого досадного недоразумения, можно прописать ту строку, что ты указал в комментарии. Хотя это не совсем считается крутым, но лучше чем при сдаче программа полетит
@user-yn5zf3gp6k
@user-yn5zf3gp6k 4 жыл бұрын
@@mxhpns7322 Протокол должен гарантировать доставку. То есть могут приходить данные после завершения программы. Чтобы не исказить данные при повторном выполнении программы с тем же портом порт остается открытым. Это я понял. А если я использую эту функцию, данные могут приходить после завершения программы?
@mxhpns7322
@mxhpns7322 4 жыл бұрын
@@user-yn5zf3gp6k Эта функция позволяет стартовать прослушивание на порту, который уже был ранее открыт. Эта функция не влияет на то, закроется ли порт после выключения программы-сервера. Для того, чтобы закрыть порт нужно применить shutdown(), затем close(). Но часто пограмму-сервер выключают с помощью комбинации клавиш Ctrl+C, и если с помощью sigaction не указать, что порт необходимо при такой ситуации закрыть, то он останется открытым еще 1-5 минут после завершения программы. И если сразу после этого запустить прогу-сервер снова, то без setsockopt(server, SOL_SOCKET, SO_REUSEADDR, ...); она не позволит прослушивать на том порту, который ещё не закрылся
@mxhpns7322
@mxhpns7322 4 жыл бұрын
@@user-yn5zf3gp6k Ответ №2 stackoverflow.com/questions/4160347/close-vs-shutdown-socket - понимание shutdown() vs close(). hea-www.harvard.edu/~fine/Tech/addrinuse.html - здесь первый короткий абзац очень точно объясняет проблему, почему после завершения процесса порт может остаться закрытым и зачем это нужно. Вот отрывок оттуда: "Чтобы сетевое соединение закрылось, оба конца должны отправить пакеты FIN (окончательные), которые указывают, что они не будут отправлять никаких дополнительных данных, и оба конца должны ACK (подтвердить) пакеты FIN друг друга. Пакеты FIN инициируются приложением, выполняющим close (), shutdown () или exit (). ACK обрабатываются ядром после завершения close (). Из-за этого процесс может завершиться до того, как ядро освободит связанный сетевой ресурс, и этот порт не может быть привязан к другому процессу, пока ядро не решит, что это сделано." Я долго пытался с этим разобраться
@user-yn5zf3gp6k
@user-yn5zf3gp6k 4 жыл бұрын
@@mxhpns7322 Спасибо
@Mentalist_1337
@Mentalist_1337 3 жыл бұрын
Возник вопрос... есть две убунты на virtualbox у обоих стоит сетевой мост в настройках сети и обе машины могут друг друга пинговать, но когда запускаю server.c другая машина не видит порт с помощью команды netstat -atnp подскажите как решить?)
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Привет. Не знаю ответа на вопрос. Может тебе подойдёт следующий вариант: Для каждой виртуалки задать значение свойства "Attached to: (Присоединен к:)" в "Internal Network (Внутренняя сеть)", а также задать одинаковые Network Names (сетевые имена) для этих машин. Источник: www.toolbox.com/tech/operating-systems/question/how-to-make-bridge-connection-between-two-virtual-machines-041510/
@mxhpns7322
@mxhpns7322 3 жыл бұрын
А я обычно NAT для машин использую в качестве настроек сети. И netstat не показывает открытые порты на другой машине, только на текущей и текущие подключения с другими машинами. Для сканирования портов любой машины по айпи адресу, можно использовать nmap. Очень хорошая идея попробовать просканировать открытые на второй виртуалке порты с помощью неё. losst.ru/kak-polzovatsya-nmap-dlya-skanirovaniya-seti
@Mentalist_1337
@Mentalist_1337 3 жыл бұрын
@@mxhpns7322 спасибо за ответ) не подскажешь еще можно ли хранить сообщения и пользователей где то в БД mysql например иии еще можно можно ли на сервере (на языке си) организовать идентификацию и аутентификацию?
@mxhpns7322
@mxhpns7322 3 жыл бұрын
@@Mentalist_1337 Да, так обычно и делают. Все данные хранятся в базе данных и для этого используются такие СУБД как mysql, sql server (на винде хорошо), oracle, postgres (бесплатная). mysql - хороший выбор, вообще здесь любой выбор хороший. Да, на сервере можно сделать это. Кратко делается так (важно не придумывать всякой дополнительной фигни и не запариваться на 3 недели): Регистрация: Клиент В ОТКРЫТОМ ВИДЕ отправляет на сервер желаемые логин и пароль, на сервере получаешь хеш от пароля, и сохраняешь в таблицу users (которую предварительно нужно добавить в БД) логин и хеш от пароля. Сам пароль хранить не надо, т.к. в случае кражи жёсткого диска сервера, злоумышленник узнает все пароли всех людей и испробует их на всех сайтах, чтобы навредить человеку. При авторизации, пользователь отправляет свои логин и пароль. На сервере нужно получить хеш от пароля и далее этот хеш сравнить с хешем, хранящимся в БД. Если совпадают, значит всё хорошо, генерируем токен (любые символы), чтобы пользователю или программе не пришлось при каждом запросе отправлять логин и пароль, сохраняем хеш токена в БД (помечая, для какого юзера он был создан), каждый последующий запрос снабжается этим токеном и проверяется на сервере таким же образом как и пароль. Токен - это, грубо, временный пароль. Т.к. пароли передаются в открытом виде, чтобы избежать атаки man on the middle, необходимо использовать https/ssl/tls (всё это одно и то же, грубо). Эти протоколы гарантируют, что нельзя подглядеть информацию, которая пересылается между компьютерами, которые организовали общение по этим протоколам. НЕ НАДО ОТПРАВЛЯТЬ ХЕШ ПАРОЛЯ ПО СЕТИ, отправляется сам пароль. Токены периодически генерируются, но это ге**рой, поэтому для начала можно и вообще без них обойтись и кешировать пароль на клиенте для каждого запроса, либо не выходить из tcp-подключения, пока клиент всё не сделает, что хочет
@mxhpns7322
@mxhpns7322 3 жыл бұрын
@@Mentalist_1337 По поводу Си. Для получения хешей можно использовать следующие библиотеки: OpenSSL, Botan. Для связи с СУБД MySQL можно использовать следующие библиотеки: libmysqlclient (dev.mysql.com/downloads/c-api/). Если охото сейчас заморачиваться с SSL, то для этого тоже подойдёт библиотека OpenSSL (stackoverflow.com/questions/11705815/client-and-server-communication-using-ssl-c-c-ssl-protocol-dont-works), но не забывай, что при релизе проекта, придётся купить сертификат SSL, например, на firstssl.ru/ - это не очень дорого
@ekaterinazubareva1123
@ekaterinazubareva1123 3 жыл бұрын
Подскажите, как сделать в vim окно вывода программы как на видео?
@viktor_borodin
@viktor_borodin 3 жыл бұрын
Это tmux, если я правильно понял вопрос
@fsagitov753
@fsagitov753 5 ай бұрын
:terminal поддерживается на vim 8.1 и выше, если не ошибаюсь
@Love_music_very
@Love_music_very Жыл бұрын
Здравствуйте, применимо ли это для С++?
@jackhrl
@jackhrl Жыл бұрын
да
@ivanpotapov9821
@ivanpotapov9821 2 жыл бұрын
А можно сделать в termux на android? Спасибо👍👍👍🔥🔥🔥
@mxhpns7322
@mxhpns7322 2 жыл бұрын
не пробовал) не знаю, но идея интересная:)
@vladimirmalazin9711
@vladimirmalazin9711 2 жыл бұрын
Да, и клиент и сервер работают без проблем, только что проверил. Только нужно иметь ввиду, что без tsu порты нужно выбирать с бОльшим значением
@majach2222
@majach2222 Жыл бұрын
Ты еще вернешься на ютуб?
@vveklenko
@vveklenko 3 жыл бұрын
Народ, кто-то знает как сделать реконект?
@viktor_borodin
@viktor_borodin 3 жыл бұрын
Знаю об этом скорее в теории а не на практике. Сам этого не делал, но много раз видел в нескольких программах, с которыми работал. Насколько я знаю просто проводить connect заново со стороны клиента. После чего необходимо выполнить функцию accept со стороны сервера. Будет получен новый активный сокет, то есть сокет для передачи информации. То есть, функции socket, bind, listen снова производить не надо. Можно сделать в цикле проверку наличия новых подключений на сервере, или как я понимаю выполнить в отдельном в ждущем режиме функцию select на сервере. Далее в случае "готового" (ready) сокета производить его "accept" в другом потоке.
@Mentalist_1337
@Mentalist_1337 3 жыл бұрын
Привет! Неудобно просить, но я не могу скомпилировать файлы)) нашел пример Linux сервера на си и Linux клиента на C++ вот pdf is.ifmo.ru/download/lanchat.pdf если не трудно расскажи как скомпилить?)
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Сейчас времени нет посмотреть, обычно всё компилится с помощью команды make
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Попробуй так. Если не получится - пиши. Может завтра посмотрю
@mxhpns7322
@mxhpns7322 3 жыл бұрын
А, тут не так. Для линукс клиента нужна библиотека qt. Линукс сервер должен компилится с помощью gcc/g++. Виндовое только на винде
@mxhpns7322
@mxhpns7322 3 жыл бұрын
Напиши мне в ватсап или телегу думаю смогу помочь: 9234495775
@Mentalist_1337
@Mentalist_1337 3 жыл бұрын
@@mxhpns7322 вроде написал в телегу
@codemonkey2190
@codemonkey2190 10 ай бұрын
Как эту штуку запустить на реальном сервере чтоб она отвечала на запросы,например если я сделал смарт устройство на микроконтроллере и допустим микроконтроллер будет посылать запросы и получать ответы по http???? Спасибо!
Работа с чужим исходным кодом на языке Си (матрица из фильма "Матрица") Часть 1
27:34
mxhpns: Программирование на Си от эксперта
Рет қаралды 2,1 М.
КАК УСТРОЕН TCP/IP?
31:32
Alek OS
Рет қаралды 85 М.
The CUTEST flower girl on YouTube (2019-2024)
00:10
Hungry FAM
Рет қаралды 43 МЛН
The Linux socket API explained
15:21
Chris Kanich
Рет қаралды 35 М.
Creating a TCP Server in C++ [Linux / Code Blocks]
43:15
Sloan Kelly
Рет қаралды 86 М.
Сокетный Клиент-Сервер на C#
58:16
Евгений Волосатов
Рет қаралды 35 М.
Уроки С++ Стек, Куча, Указатели (11)
26:06
Software Development
Рет қаралды 37 М.
Сеть и сокеты. База для backend разработчика.
17:11
Константин Козловский
Рет қаралды 47 М.