Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.25;
Скачать: CL | DM;

Вниз

while ... do Socket.Open; Socket.SendText( hello world );   Найти похожие ветки 

 
denkop ©   (2004-02-21 23:12) [0]

Решил состряпать код для рассылки текстовых сообщений всем компьютерам лок. сети и конечно чтобы работала без сервера (т.к. такого не имеется). Вот кусок не работающего кода:

i:=0;
while i<=ListBox2.Count-1 do
begin
  ClientSocket1.Close;
  ClientSocket1.Address:=ListBox2.Items[i];
  ClientSocket1.Port:=10048;
  ClientSocket1.Open;
  ClientSocket1.Socket.SendText("hello");
  i:=i+1;
end;

Ничего не посылает ни вылетает никаких ошибок, а просто молчит. Если кусок соединения и посылки посадить на разные батоны, все проходит ОК, но это всего лишь один ip (а у меня их много).
Напрашивается вывод, что на соединение уходит время, а программа этого времени не ждёт и делает то, что ей нужно. Возникает логичный вопрос, как правильно дождаться соединения сокета?

Пробовал так:
..........
while not ClientSocket1.Connected do
Application.ProcessMessages;
Это длится не скончаемо...


 
SergP ©   (2004-02-22 00:08) [1]

А почему бы тебе не использовать соответствующие события ClientSocket"а?


 
Verg ©   (2004-02-22 08:21) [2]

Режми сокета какой? ctBlocking, ctNonBlocking?


 
denkop ©   (2004-02-22 15:04) [3]

Пробовал ставить SendText() в OnConnect и в OnConnecting, возникает Exception Access Violation......

Режим NonBlocking.

Идея состоит в том чтобы сделать чат без сервера. У каждого клиента запущена программа в котрой есть сокетовый сервер и клент. И если нужно послать месагу, то соединяемся по очереди с каждым сервером и шлём месаги. Вот.

P.S. Не знаю, может это не лучший способ, но другого я пока не знаю, т.к. в сетях я чайник, поэтому прошу не браниться если скажу глупости.


 
denkop ©   (2004-02-22 16:38) [4]

Всё разобрался. У меня у серверсокете стояла глупость на OnClientRead. Глупость убрал, поставил в OnConnect SendText() и всё заработало :)!

С вашего позволения попутный вопрос. Как проверить открыт ли у удалённого чатника порт (т.е. запущен ли сервер)? Когда сервера нет, вылетает ошибка следующего содержания Asynchronous socket error 10049. Хотя и у клиента и у сервера прописан порт 10048 для соединения, а как я понял из ошибки проблема с портом 10049.


 
Verg ©   (2004-02-22 16:41) [5]

В неблокирующем режиме начинать передачу можно только после возникновения события OnWrite
Т.е. вызываем начало соединения Clientsocket1.active := true;
Можт возникнуть либо OnError либо OnWrite
Если OnError, то зануляем ErrorCode, закрываем сокет socket.close;
Если OnWrite, то передаем нужные данные. В твоем случае-это просто SendText. Проверь результат выполнения этой ф-ции. Он должен быть равен длине переданной строки.
Закрываем сокет socket.close
В результате, так или иначе, получаем событие OnDisconnect - конец сенса (удачного или не удачного).
В твоем случае я бы поставил сообщение форме (PostMessage(Handle, WM_NEXT_CONNECTION,....), в обработчике, которого

   if I < ListBox2.Items.Count then
   begin
     ClientSocket1.Address:=ListBox2.Items[i];
     ClientSocket1.Port:=10048;
     ClientSocket1.Active := true;
     inc(I);
   end;

I - поле формы

С неблокирующими сокетами надо быть очень аккуратным при отправке данных.
Посмотри исходник ScktComp реализацию ф-ции SendStreamPiece чтобы понять некоторые тонкости.


 
Verg ©   (2004-02-22 16:56) [6]


> Asynchronous socket error 10049.

Это номер (код) ошибки, а не порта :)))


 
Falendysh ©   (2004-02-22 19:48) [7]

А как вообще в D7 работать с ServerSocket и ClientSocket если их там нет, а есть TCPServer и TCPClient. Может вы мне подскажите?
Спасибо.


 
Delphin ©   (2004-02-23 00:07) [8]

В твоей ситуации проще использовать UPD, a не Tcp


 
denkop ©   (2004-02-23 01:06) [9]

to Verg >> вроде вкурил :)

Вот как сделал я:

при нажатии на батон отсылки выполняется это:

var
s:string;
i:integer;
begin
i:=0;
if IPList.Count=0 then
begin
  ShowMessage("Не найдено ни одного пользователя."+#10#13+
              "Попробуйте позже");
  IPList.Items.Add("127.0.0.1"); //это для теста без наличия сети
  UsersList.Items.Add("localhost"); //это для теста без наличия сети
//   Exit;
end;
while i<=IPList.Count-1 do
begin
  Client1.Close;
  Client1.Host:=IPList.Items[i];
  CurrUser:=IPList.Items[i];
  Client1.Port:=10048;
  Client1.Open;
  while not IsConnected do
   Application.ProcessMessages;
  s:=Cmd[1]+CurrUser+">"+MessEdit.Text; //Cmd[]-условные команды. в дальнейшем може ещё чего хорошего (или плохого:) ) добавится.
  Client1.Socket.SendText(s);
  Client1.Close;
  i:=i+1;
end;
end;

Вот это в OnConnect сокета:
IsConnected:=True;
в OnDisconnect соответвенно:
IsConnected:=False;
в OnError это:
Socket.Close;

Вот собственно и всё.

to verg >>
Остался маленький вопрос. Твой пост это альтернатива или исправление ошибок моему. Другими словами может ли мой код правильно работать (работать он работает, но я не у верен насколько это всё происходит правильно с точки зрения Били и etc :) )

Я бы с больши`м удовольствием бы почитал бы это, но времени как всегда не хватает (можно выделить только после 01:00am, но и спать когда-то тоже нужно!), поэтому перебиваюсь добротой людей. :) Хотя ScktComp очень занимательная вещь для таких сетевых чайников как я.


> > Asynchronous socket error 10049.
>
> Это номер (код) ошибки, а не порта :)))


Мда, верно, я просто не выспался, ну я же попросил прощения за глупости (=|=)...

to Falendysh >>
Вот так в D7 включаются сокеты:
unit RegSock;
interface
uses Classes, ScktComp;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents("Internet", [TServerSocket]);
RegisterComponents("Internet", [TClientSocket]);
end;
end.

to Delphin >>
Можешь в кратце разъяснить как всё это дело организовать по UDP(посл-ть опер-й и пр.). Это будет задание на нескушный досуг следующих выходных.


 
Falendysh ©   (2004-02-23 12:24) [10]

Прошу меня извинить, но
unit RegSock;
interface
uses Classes, ScktComp;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents("Internet", [TServerSocket]);
RegisterComponents("Internet", [TClientSocket]);
end;
end.

не работает. Возникает ошибка Invalid Component Registration


 
Verg ©   (2004-02-23 13:09) [11]


> Твой пост это альтернатива или исправление ошибок моему.
> Другими словами может ли мой код правильно работать (работать
> он работает, но я не у верен насколько это всё происходит
> правильно с точки зрения Били и etc :) )


Это исправление ошибок. Именно касается асинхронных сокетов, в частности TClientSocket. Два ключевых момента:
1. Признаком установленного соединения ДОЛЖНО СЧИТАТЬСЯ
событие OnWrite, а не OnConnect.
2. Передавая данные, необходимо понимать, что операция записи в любой момент может закончиться неудачей с мотивом WSAEWOULDBLOCK - это НЕ фатальная ошибка, это просто указание дождаться следующего OnWrite, перед тем как пытаться отправить следующие данные. Это, т.о., означает ОБЯЗАТЕЛЬНЫЙ анализ результатов выполения всевозможных ф-ций по отправке данных. Будь то sendtext, sendbuf или что-то иное.

И зачем эти извращения с application.processmessages? Почему не хочешь просто обрабатывать события сокета, перекидыватя свой конечный автомата из одного состояния в другое?
Т.е. вобще-то, впечатление такое, что тебе пока рановато использовать асинхронный режим. Используй пока ctBlocking. Опыт придет, понимание опять же, тогда и асинхронный режим будет к месту.

Билли тут не виноват. Скорее наоборот, полноценная асинхронность в его Win32-WinSock2 стала не мечтами стандарта Posix 1g, а вполне приемлимой действительностью.

PS С Праздником!


 
DenKop ©   (2004-02-24 16:38) [12]

to Verg >
Это исправление ошибок. Именно касается асинхронных сокетов, в частности TClientSocket. Два ключевых момента:
1. Признаком установленного соединения ДОЛЖНО СЧИТАТЬСЯ
событие OnWrite, а не OnConnect.
2. Передавая данные, необходимо понимать, что операция записи в любой момент может закончиться неудачей с мотивом WSAEWOULDBLOCK - это НЕ фатальная ошибка, это просто указание дождаться следующего OnWrite, перед тем как пытаться отправить следующие данные. Это, т.о., означает ОБЯЗАТЕЛЬНЫЙ анализ результатов выполения всевозможных ф-ций по отправке данных. Будь то sendtext, sendbuf или что-то иное.


Мда всё не так просто как я думал

И зачем эти извращения с application.processmessages? Почему не хочешь просто обрабатывать события сокета, перекидыватя свой конечный автомата из одного состояния в другое?
Т.е. вобще-то, впечатление такое, что тебе пока рановато использовать асинхронный режим. Используй пока ctBlocking. Опыт придет, понимание опять же, тогда и асинхронный режим будет к месту.


Может не совсем грамотно, но более просто для понимания. А насчёт рановато это возможно. Я вообще предполагал, что асинхронный сокет использовать намного проще. Наверное ошибался... Придётся поискать примеры блочного режима :(

Спасибо за помощь!

З.Ы. Благодарю. Тебя так же!

to Falendysh >

У меня прошло без проблем...



Страницы: 1 вся ветка

Текущий архив: 2004.04.25;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.028 c
14-1080915958
Delphi5.01
2004-04-02 18:25
2004.04.25
Рецепт плавленого ...


1-1081298822
olhovik
2004-04-07 04:47
2004.04.25
Вставка в .ехе


14-1081163956
syte_ser78
2004-04-05 15:19
2004.04.25
Вопрос по Olympus D-380


1-1081367285
777666
2004-04-07 23:48
2004.04.25
Вертикальный разделитель в меню. Как?


1-1081134995
Извращенец2
2004-04-05 07:16
2004.04.25
Уменьшение размеров приложения