![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с разрывом socket соединения [D5, D6, D7, Win2k]
Furyous © (2004-06-23 08:10:00)Такая проблема: если в чате(ClientSocket) у клиента завершить процесс, то сервак выдаёт ошибку сокета и падает. Нужно как-то закрывать соединение с таким клиентом, но ничего не получается.
Furyous (2004-06-24 15:08:00) [21]У меня хелп не пашет, ваще ни в какой проге хелп не пашет.
Digitman (2004-06-24 15:05:00) [22]
> Furyous © (24.06.04 15:03) [27]
и что ?
у тебя с аглицким проблемы ?
Furyous (2004-06-24 15:03:00) [23](hwnd, cardinal, wparam, lparam)
Digitman (2004-06-24 14:56:00) [24]
> Там какие-то страные параметры
это какие же ?
Furyous (2004-06-24 14:46:00) [25]Я ваще не знаю как юзать postmessage. Там какие-то страные параметры, хз чё писать там.
Digitman (2004-06-24 14:16:00) [26]
> Furyous © (24.06.04 13:58) [23]
> Чёт не выходит
а входит ?
не сподибишься ли показать, как ты это САМ пытаешься реализовать ?
Furyous (2004-06-24 13:58:00) [27]Чёт не выходит. Мона небольшой примерчик плз?
Verg (2004-06-24 13:45:00) [28]Дело может быть в том, что на момент вызова ClientDisconnect список активных соединений еще содержит данное соединение. Т.о., ты рассылаешь сообщение всем, включая и того клиента, который отключился.
Методом postmessage перенеси рассылку сообщений всем из ServerSocket1ClientDisconnect в отдельную процедуру-обработчик.
Furyous (2004-06-24 13:12:00) [29]Asynchronous Socket Error 10053. В лучшем случае сервак просто закывает соединение со всеми.
Verg (2004-06-24 11:16:00) [30]В чистом виде на разрыв соединения никаких ошибок не возникает и возникать не должно.
> то сервак выдаёт ошибку сокета и падает
Какую ошибку, конкретно?
Digitman (2004-06-24 10:17:00) [31]
> Term (24.06.04 09:53) [17]
например, см. [18]
контр.сумма, в принципе, необязательна
достаточно того, что принимающая сторона, получив сначала размер сообщения, знает с этого момента, сколько байт сообщения следует ожидать и может накапливать поступающие "порции" где-то во временном буфере до тех пор пока не будет принято полное ожидаемое сообщение, и только после этого анализировать врем.буфер
ValeraVV (2004-06-24 10:06:00) [32]в начале перадавать размер сообщения, а в конце его контрольную сумму
Term (2004-06-24 09:53:00) [33]
> Digitman © (24.06.04 09:12) [15]
> - в 1-м событии сервер получил строку '#N ВА'
> - в 2-м событии сервер получил строку 'СЯ ПУП'
> - в 3-м событии сервер получил строку 'КИН'
и как быть в такой ситуации??? если количество частей на которые может распасться сообщение не известно???
Evgeny V (2004-06-24 09:17:00) [34]Для асинхронных сокетов exception можно поймать на уровне приложения, например использовать TApplicationEvents, и в OnException его отслеживать ESocketError
Digitman (2004-06-24 09:12:00) [35]
> Furyous © (24.06.04 08:21) [14]
если клиент вызывом SendText() послал, например, строку '#N ВАСЯ ПУПКИН', это отнюдь не означает, что на сервере возникнет единственное событие OnClientRead(), и в обработчике этого события сервер вызовом ReceiveText() получит в точности такую же строку
представь себе ситуацию, что на сервере возникло, например, 3 последовательных события OnClientRead(), при этом
- в 1-м событии сервер получил строку '#N ВА'
- в 2-м событии сервер получил строку 'СЯ ПУП'
- в 3-м событии сервер получил строку 'КИН'
т.е. данные на сервер могут поступать отдельными фрагментами потока
если "склеить" эти 3 "фрагмента", то как раз и получится оригинальный отправленный клиентом текст '#N ВАСЯ ПУПКИН'
событий таких может возникнуть и более, заранее прогнозировать их число бессмысленно, гораздо более важно то, что последовательность отправляемых данных в точности соответствует последовательности принимаемых данных
в условиях интерсети это абсолютно реальная ситуация !!!
и вот теперь думай головой ... весь твой алгоритм - коту под хвост, когда ты его попытаешься использовать за рамками "тепличных" условий односегментной ЛВС.. да и в ЛВС рано или поздно алгоритм твой даст сбой из-за неучитывания тобой этих особенностей
Furyous (2004-06-24 08:21:00) [36]Потому что с них начинается любая мессага. Да чат, работает стабильно, тока надо баг убрать с вылетанием сервака.
Digitman (2004-06-24 08:08:00) [37]ему про фому, он все про ерему гнет ..
> Furyous © (24.06.04 05:00) [12]
> #N - это юзера запросить имя
с чего ты взял, что первые два символа принятой по ReceiveText() строки обязательно будут равны или '#N' или '#M' или '#F' '#P' и ничему другому ?
Furyous (2004-06-24 05:00:00) [38]#N - это юзера запросить имя, button3 бред, не обращай внимания. А fstream - это я для передачи файла делал, пока не пашет.
Verg (2004-06-23 20:03:00) [39]
> [4] Furyous © (23.06.04 16:37)
> вот сервер:
> procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
> Socket: TCustomWinSocket);
> var s, c, l: string;
> i: Integer;
> fstream: tmemorystream;
> begin
> fstream := tmemorystream.Create;
> s := Socket.ReceiveText;
>
> if (Copy(s,1,2) = '#N') then begin
> Delete(s,1,2);
> ListBox1.Items.Add(s);
> s := '#U';
> for i := 0 to ListBox1.Items.Count - 1 do
> s := s + ListBox1.Items[i]+';';
> for i := 0 to ServerSocket1.Socket.ActiveConnections-1
> do
> ServerSocket1.Socket.Connections[i].SendText(s);
> Exit;
> end;
> if (Copy(s,1,2) = '#M')or(Copy(s,1,2) = '#P') then begin
> for i := 0 to ServerSocket1.Socket.ActiveConnections-1
> do
> ServerSocket1.Socket.Connections[i].SendText(s);
> Exit;
> end;
> end;
> { if (Copy(s,1,2) = '#F') then
> begin
> ServerSocket1.Socket.Connections[0].SendStream(fstream);
> end;}
Хм... У тебя на самом деле в коментариях SendStream? И на каждый ServerSocket1ClientRead зваодится по новому fstream := tmemorystream.Create;
который никто освобождать и не соьбирался?
А вообще опять: как же наконец объяснить, что размеры отправляемых порций НЕ РАВНЫ в общем случае размерам принимаемых при поточном обмене, коим является TCP/IP.
Они МОГУТ оказаться равными при некоторых "тепличных" условиях, но никогда на это расчитывать нельзя!
> s := Socket.ReceiveText;
>
> if (Copy(s,1,2) = '#N') then begin
Ну и что это за сравнения с #N, а если "приплыло" только #, а все остальное будет позже?
Verg (2004-06-23 19:54:00) [40]Я че-то не пойму. Это что тут?::
> procedure TForm1.Button3Click(Sender: TObject);
> var
> c,l : string;
> begin
>
> SetLength(l, StrLen(PChar(c)) + 1);
> StrLCopy(@l[1], PChar(c), Length(l) - 1);
> DataSize := StrToInt(l);
> Data := TMemoryStream.Create;
>
> Delete(c, 1, Length(l));
> Reciving:= true;
>
> end;
Бред какой-то....