Конференция "Сети" » Помогите с winsocket в WinAPI [D6, D7, WinXP]
 
  • chemelin (15.01.08 15:40) [20]

    > Тут не затвердением пахнет - тут пахнет многократным штудированием
    > от начала до конца)

    признаюсь, WinAPI учил изначально на C++ , но WinAPI  на Delphi очень пож на WinAPI С++.
    И хватит меня критиковать!
  • Сергей М. © (15.01.08 16:04) [21]

    > chemelin   (15.01.08 15:38) [19]


    > как то исправить


    Оч просто - либо задействовать неблок.режим слушающего гнезда либо вынести "стояние на прослушивании" в отдельный кодовый поток.


    > И хватит меня критиковать


    Изволишь чтобы тебя хвалили за принципиальное нежелание читать документацию ?
  • Григорьев Антон © (15.01.08 16:10) [22]

    > chemelin   (15.01.08 15:38) [19]
    > ещё один вопрос! Когда сервер стоит на прослушивании, ожидания
    > приёма информации, он как будто бы повисает и никаких действий
    > выполнить нельзя,
    > все из за цикла while (true) do это как то исправить

    Это не только из-за цикла while True do, это, в основном, из-за того, что функция accept по умолчанию работает в блокирующем режиме. Вариантов исправления много:

    1. Использовать select с таймаутом и вызывать accept только если select показал готовность сокета

    2. Перевести слушающий сокет в неблокирующий режим.

    3. Используя WSAAsyncSelect, связать сокет с оконным сообщением и вызывать accept только по приходу этого сообщения.

    4. Используя WSAEventSelect, связать сокет с событием и при необходимости проверять состояние этого события с помощью WSAWaitForMultipleEvents.

    5. Использовать AcceptEx в режиме перекрытого ввода-вывода.

    6. Делать accept в отдельной нити, которая больше ничем другим заниматься не будет - тогда её зависание всей остальной программе будет по барабану.

    Ну и от цикла тоже (за исключением варианта 6), конечно, надо избавиться. Например, если вы выберете вариант 1 или 2, можно проверять по таймеру.
  • chemelin (15.01.08 16:21) [23]

    > Изволишь чтобы тебя хвалили за принципиальное нежелание
    > читать документацию ?

    Учту!


    > Григорьев Антон

    Спасибо!
  • Григорьев Антон © (15.01.08 16:33) [24]

    > chemelin   (15.01.08 12:30)  
    > если можно исходник или ссылки на статьи

    Кстати, а вот это видели?
    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1021
    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1060
  • chemelin (15.01.08 17:19) [25]

    > 6. Делать accept в отдельной нити, которая больше ничем
    > другим заниматься не будет - тогда её зависание всей остальной
    > программе будет по барабану.

    Покажи пожалуйста на примере я что-то не очень понял как делать accept в отдельной нити, статью прочитал. Извиняюсь! Буду очень благодарен!
  • Григорьев Антон © (15.01.08 18:34) [26]

    > chemelin   (15.01.08 17:19) [25]

    И что же конкретно вам непонятно? С нитями работать вроде умеете...
  • chemelin (15.01.08 18:44) [27]
    Никак не могу убрать блокировку! ((((
    Пробую это, не помогает, точнее с значением "1", ошибка:

       Arg:=1;
     IOCtlSocket(sServerListen,FIONBIO,Arg);

  • Григорьев Антон © (15.01.08 19:22) [28]
    Так вы в отдельную нить выносите или неблокирующий сокет делаете?

    И какая же ошибка возникает?
  • chemelin (15.01.08 19:28) [29]
    Вот смотрите:

    //Создание Сервера
    procedure crestserver;
    var
    wData : WSADATA;
    sServerListen, sClient : TSOCKET;
    localaddr, clientaddr : sockaddr_in;
    iSize : Integer;
    s1 : TCPClientThread;
    begin
    // Загрузка WinSock
    if WSAStartup(MAKEWORD(1,1), wData) <> 0 then
    begin
      MessageBox(0, 'Не могу загрузить WinSock', 'Ошибка', 0);
      exit;
    end;

    // Создание сокета
    sServerListen := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if sServerListen = INVALID_SOCKET then
     begin
      MessageBox(0, 'Ошибка создания сокета', 'Ошибка', 0);
      exit;
     end;

    // Запонение структуры адреса
    localaddr.sin_addr.s_addr := htonl(INADDR_ANY);
    localaddr.sin_family := AF_INET;
    localaddr.sin_port := htons(5050);

    //Связывание сокета с локальным адресом
    if bind(sServerListen, localaddr, sizeof(localaddr)) = SOCKET_ERROR then
     begin
      TestWinSockError('Bind');
      exit;
     end;

    //Прослушивание
    if TestFuncError(listen(sServerListen, 4), 'Listen') then
     exit;

    MessageBox(0, 'Сервер запущен', 'Внимание!!!', 0);

    while (true) do
     begin
      iSize := sizeof(clientaddr);

      //Приём нового соединения

      sClient := accept(sServerListen, @clientaddr, @iSize);

      if sClient = INVALID_SOCKET then
       begin
        TestWinSockError('accept');
        break;
       end;

      // Соединение принято, создаём поток
      s1:=TCPClientThread.Create(true);
      s1.Sock:=sClient;
      s1.Resume;
     end;
    closesocket(sServerListen);
    end;


    При таком создании сервера происходит повисание, я толком не понял что такое "нить". Куда и какой здесь нужно вставить строки кода что бы не происходило повисание?? Помогите, я просто с сокетами работал очень мало.
  • Григорьев Антон © (15.01.08 19:52) [30]
    Нить - это то, что вы называете потоком. Я предпочитаю слово "нить", потому что поток - это не только thread, но и stream, возникает путаница. А код надо вставлять в тело специально созданной для этого нити. Вы же TCPClientThread сделали, значит, и с этим разберётесь.
  • Сергей М. © (15.01.08 19:57) [31]

    > chemelin


    Ты действительно идиот или оным прикидываешься ?)
  • chemelin (15.01.08 20:36) [32]

    > Ты действительно идиот или оным прикидываешься ?)

    прикидываюсь
  • Сергей М. © (15.01.08 21:18) [33]
    А смысл ?
  • chemelin (15.01.08 21:26) [34]
    Спасибо Вам за поддержку, уже все сделал, все работает, мне было лень читать документацию.
 
Конференция "Сети" » Помогите с winsocket в WinAPI [D6, D7, WinXP]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]