Асинхронные сокеты winsock

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by blackbox, 13 Nov 2015.

  1. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Никак не могу найти номальную инфу на русском. На форумах нахожу какие-то куски кода, но они не откомментированны в самых нужных местах, поэтому остается только догадываться что да как. Есть ли годные статьи/примеры на эту тему? Еще немного погуглил и увидел что асинхронные и неблокирующие - разные вещи. В общем, гуру, поясните плиз.
     
    #1 blackbox, 13 Nov 2015
    Last edited: 13 Nov 2015
  2. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    http://forum.antichat.net/threads/432145/
    Вот недавно писал портянку. + я в теме http://forum.antichat.net/threads/432412/ давал ссылку на исходники сервера RemoTouchpad, изучи файд main_ui.cpp
    Там реализован вариант, когда сообщение о том что в сокете что-то появилось отправляется окну приложения, а он уже в своем жизненном цикле разбирает его, это вот и называется неблокирующие сокеты. К тому же это окно не отображается на экране никак, в данной реализации я просто добавил иконку в трей с менюхой.
    Функцию StartServer смотри там есть вызов WSAAsyncSelect(sServerListen,hWnd,WM_SOCKET,FD_READ) - что означает когда поступает на сокет сервера операция чтения - окну hWnd отправляется сообщение WM_SOCKET
    Ну а уже в теле функции окошка GarikWinProc которая эту операцию обрабатывает.

    Самое что плохое ты ведь пытаешься писать на С#, которого я не знаю, уверен там в .NET свои классы и обертки под все эти задачи, например как boost asio в С++
     
    _________________________
    #2 Gar|k, 17 Nov 2015
    Last edited: 17 Nov 2015
  3. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Серверная часть как-раз на си, но там голое приложение без окон, а асинхронные winsock, я так понял на оконных сообщениях завязаны. Но вообще я смотрю что информации почему-то по теме не густо.
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Просто нужно знать что искать http://habrahabr.ru/post/59282/ и учить технический англицкий, рано или поздно придется столкнутся с отсутсвием актуальной информации.

    Вот например MSDN https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms742203(v=vs.85).aspx
    Там есть пример использования Overlapped Socket I/O, как бы это и есть неблокирующий режим. Как это работает ты создал структуру WSAOVERLAPPED с событием на чтение допустим вызвал функцию WSASend она отправила данные какие-то куда-то... А где-то в потоке у тебя крутится основной событийный цикл с WSAWaitForMultipleEvents... В общем да без 100 грамм не разобраться, с наскоку, смотри примеры на MSDN там еще есть разделы Usage https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms740632(v=vs.85).aspx

    Проще использовать уже готовые библиотеки типа libevent или libev
     
    _________________________
    #4 Gar|k, 18 Nov 2015
    Last edited: 18 Nov 2015
    blackbox likes this.
  5. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Спасибо за линки, посмотрю. Хотя сейчас в приложении другие вопросы повсплывали. Возможно еще тред создам.
     
  6. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    Просто принцип построения асинхронных приложений совершенно другой - это нужно понимать. Тут операции неблокирующие и это надо понимать. А когда что-то происходит система тебя сама об этом оповещает... Основной алгоритм подобной программы хорошо описан в документации libevent
    Есть какой-то основной цикл который ждет чего-то, возникновения каких либо событий... например пришло событие пришли данные - ты дергаешь получи... потом пришло событие получил. ты анализируешь данные... И все это надо замутить так что бы не было ожиданий... между "получи данные" и "получил данные" система тебя уведомит сама когда это произойдет - смысл в том что если у тебя много клиентов (допустим на сервере) ты таким макаром обрабатываешь кучу клиентов ассинхронно не тормозя работу самого сервера, не тратя время на ожидание "отправь - отправил" "получи - получил"

    Так вот вот для реализации подобного поведения программы система предоставляет тебе различные API event, select, IOCP (если мы говорим прод windows)
    Стало понятнее? )

    Вон выше где я тебе ссылку давал я юзал API setect - WSAAsyncSelect НО только для 1 сокета - для серверного который слушает что ему шлют (там UPD) сервер, а прием и отправка у меня синхронные - так как у меня окошко то не видно и мне пофиг будет оно тормозить или нет... к тому же UPD это не TCP там нет проверок ушло сообщение пришло ли оно... так то можно в случае TCP сервера после accept (FD_ACCEPT) и для клиентского сокета вызывать WSAAsyncSelect привязывая его к окну - что бы потом сообщение из сокета клиента обрабатывались асинхронно.
    Подобный алгоритм годится для простого сервера, если у тебя там не 10 000 клиентов, если больше уже надо думать о IOCP и переписывать приложение в соотвествием с документацией этого алгоритма.
     
    _________________________
    blackbox likes this.
  7. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    WSAAsyncSelect, как я понял, он только для оконного приложения пригоден или можно в консольном юзать? Там вроде сообщения как оконные обрабатываются или я не врубился.
     
  8. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    _________________________
    blackbox likes this.