Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.12.2012, 06:38   #21
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Блин, вот так всегда, только спросишь, и косяк найдешь.
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 19.12.2012 в 06:43.
Rin вне форума Ответить с цитированием
Старый 19.12.2012, 06:49   #22
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

косяк косяком, но именно на ответе (send) мой пример резко усложнится
можно и без усложнений, но тогда нет гарантии полного/целостного ответа, т.е. в локальной быстрой сети работать возможно будет, а в медленных сетях интернета - случайным образом нет
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 19.12.2012, 08:36   #23
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Цитата:
косяк косяком, но именно на ответе (send) мой пример резко усложнится
можно и без усложнений...
Доброго времени суток, Slym. Без усложнений как раз и сделал.
Клиент без циклов и потоков. Сервер - тот код, который ты дал.
Клиент посылает серверу send и ждет ответа 5 сек (с помощью select). Сервер в потоке получает сообщение и посылает ответ. Клиент получает ответ.
Правда не работает при нескольких пользователях. Но это уже мелочи.
Оффтоп.
Спать пора. Мозг практически не соображает.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 19.12.2012, 08:46   #24
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

незачем ждать... послал - забыл... на меленьких разовых посылках должно канать... даже размер посланного можно не контролировать
Код:
program Project1;
{$APPTYPE CONSOLE}
uses  SysUtils,Windows,WinSock;

var
  Data:TWSAData;
  listen_socket:TSocket;
  Sockets:array of TSocket;
  Addr:TSockAddr;
  I,J:Integer;
  FDSet:TFDSet;
  buf: string;
  Timeout: TTimeVal;
begin
  WSAStartup($101,Data);
  listen_socket:=Socket(AF_INET,SOCK_STREAM,0);
  Addr.sin_family:=AF_INET;
  Addr.sin_port:=HToNS(25);
  Addr.sin_addr.S_addr:=InAddr_Any;
  If Bind(listen_socket,Addr,SizeOf(TSockAddr))=0 then exit;
  If Listen(listen_socket,SoMaxConn)=0 then exit;

  TimeOut.tv_sec:=60;

  while true do
  begin
    FD_ZERO(FDSet);
    FD_SET(Listen_socket,FDSet);
    for i:=Low(Sockets) to High(Sockets) do
      if Sockets[i]<>INVALID_SOCKET then
        FD_SET(Sockets[i],FDSet);

    if select(0,@FDSet,nil,nil,@TimeOut)=0 then Continue;

    if FD_ISSET(Listen_socket,FDSet) then
    begin
      i:=Low(Sockets);
      while i<=High(Sockets) do
      begin
        if Sockets[i]=INVALID_SOCKET then
          break;
        inc(i);
      end;
      if i>High(Sockets) then
        SetLength(Sockets,i);
      j:=SizeOf(TSockAddr);
      Sockets[i]:=Accept(listen_socket,@Addr,@j);
    end;

    for i:=Low(Sockets) to High(Sockets) do
    begin
      if FD_ISSET(Sockets[i],FDSet) then
      begin
        SetLength(buf,4096);
        SetLength(buf,recv(Sockets[i],buf[1],Length(buf),0));
        if length(buf)= 0 then
        begin
          CloseHandle(Sockets[i]);
          Sockets[i]:=INVALID_SOCKET;
        end else
        begin
          writeln(buf);
          if send(Sockets[i],buf[1],Length(buf),0)=SOCKET_ERROR then
          begin
            CloseHandle(Sockets[i]);
            Sockets[i]:=INVALID_SOCKET;
          end;
        end;
      end;
    end;
  end;
end.
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 19.12.2012 в 08:52.
Slym вне форума Ответить с цитированием
Старый 19.12.2012, 18:13   #25
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

О, спасибо за код, но я уже и подключение нескольких клиентов сделал. Одного не могу понять. Почему я не могу сделать массовой рассылки всем клиентам?
Если пишу так:
Код:
/ получаем данные от клиента/клиентов
    for i:=Low(Sockets) to High(Sockets) do
    begin
      if FD_ISSET(Sockets[i],FDSet) then
      begin
        SetLength(buf,4096);
        SetLength(buf,recv(Sockets[i],buf[1],Length(buf),0));
// если буфер пуст, то клиент закрыл соединение.
// нужно удалить сокет из массива.
        if length(buf)= 0 then
        begin
          CloseHandle(Sockets[i]);
          Sockets[i]:=INVALID_SOCKET;
          FD_clr(Sockets[i],FDSet);
        end else
        begin
// иначе вывести данные
          Form1.Memo1.Lines.Add(buf+' сокетов в FDSet:'+inttostr(FDSet.fd_count)+
          '   сокетов в Sockets:'+inttostr(High(sockets)+1));
          SetLength(buf1,4096);
          send(sockets[i],buf1[1],length(buf1),0);
      end;
      end;
    end;
  end;
то он принимает данные от клиента, отвечает клиенту, а клиент принимает. Даже если несколько клиентов, то все нормально.
Но если в последних строках добавить цикл для отправки всем клиентам, то gameover.
Код:
..................
        begin
// иначе вывести данные
   for j:= 0 to high(sockets) do
     begin
          Form1.Memo1.Lines.Add(buf+' сокетов в FDSet:'+inttostr(FDSet.fd_count)+
          '   сокетов в Sockets:'+inttostr(High(sockets)+1));
          SetLength(buf1,4096);
          send(sockets[j],buf1[1],length(buf1),0);
     end;
      end;
      end;
    end;
  end;
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 19.12.2012, 18:39   #26
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

что ты отправляешь? в buf1 мусор! ты отправляешь мусор. а вот в buf полезные данные которые ты игнорируешь
второе: ты уверен что клиент ждет посылку или иногда проверяет входной буфер?
клиента сюда давай, тот что в первом посте читает только 1 раз при соединении и все...
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 19.12.2012 в 18:43.
Slym вне форума Ответить с цитированием
Старый 19.12.2012, 18:58   #27
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Вот я тормоз. Клиенты же не ждут посылки. Точно! Спасибо.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 19.12.2012, 20:41   #28
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию [B]Наконец-то[/b]

Все, работает! Благодарю за огромную помощь, Slym. Без вас бы ничего не получилось! Выкладываю "сыры" чата. Вдруг кому понадобится.
Вложения
Тип файла: rar чат на winsock.rar (18.9 Кб, 26 просмотров)
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Telnet клиент на сокетах an1s1 Общие вопросы .NET 1 19.07.2012 17:38
Статья: Низкоуровневое сетевое программирование. Пишем клиент/серверное приложение на сокетах Беркли oleg kutkov C/C++ Сетевое программирование 42 22.01.2011 00:35
Чат на сокетах yandzee Общие вопросы C/C++ 6 11.12.2010 14:50
Простейшие клиент-сервер на сокетах: почему ошибка 10060 kolchakA Общие вопросы C/C++ 7 01.12.2009 08:14