Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.027 c
11-1065517049
Yury Sidorov
2003-10-07 12:57
2004.04.25
Неуказанное важное изменение в KOL 1.85


1-1081146956
Comp
2004-04-05 10:35
2004.04.25
Поиск шрифта


1-1081337143
Макс Шабанов
2004-04-07 15:25
2004.04.25
Как добавить большую таблицу в RichEdit ?


7-1078177032
Sergeika
2004-03-02 00:37
2004.04.25
Как отловить нажатие мультимедиа клавиши на клавиатуре?


11-1063206824
Кладов
2003-09-10 19:13
2004.04.25
Неизвестные секреты Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский