Форум: "Сети";
Текущий архив: 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.034 c