if(((MyStruct*)Socket->Data)->NameStr=="MassSender")
{
MessageStr=Socket->RecievedText();
//затем рассылай сообщение...
for (int i=0; i< Server->Socket->ActiveConnections; i++)
{
Server->Socket->Connections->SendText(MessageStr);
}
}
TServerSocket
как в TServerSocket послать текст по всем соединениям...и вообще как посоветуете сделать идентификацию соединений, думаю что-нить типа отдельного массива забодяжить в который буду пихать каждое соединение, но вот детально как? Надо ведь еще делать что-нить типа free() и еще чего-нить...
for (int i=0; i< ServerSocket->Socket->ActiveConnections; i++)
{
ServerSocket->Socket->Connections->SendText("Server close, bai-bai...")
ServerSocket->Socket->Connections->Close();
Application->ProcessMessages();
}
идентифицировать соединение:
запихни указатель на структуру в свойство Data
__fastcall struct MyStruct
{
String NameStr;
int TrafficIn;
int TrafficOut;
}
MyStruct * MS=new MyStruct;
MS->NameStr="Наш любимый юзер подключился";
MS->TrafficIn=0;
MS->TrafficOut=0;
ServerSocket->Connections->Data =MS;
Создавать структуру можно в событии
ClientConnectionAccept
и при этом ее нужно запихивать в Socket->Data
удаляй структуру в событии OnClientDisconnect или OnClientError
присутствует такая странность onRead при посылке месяги по всем коннекшинам месяга шлется только на первый...почему? не могу понять...
"такая странность onRead"
что за странность ?
наверно что-то с индексами...
Если как в моем примере после отправки сообщения закрываешь соединение, то может быть нужно подправить значение "i" ведь после закрытия соединения их общее кол-во уменьшилось... или закрывать соединения в отдельном цикле
не проверял, может сработает, а может нет:
while(ServerSocket->Socket->ActiveConnections!=0)
{
ServerSocket->Socket->Connections[0]->Close();
Application->ProcessMessages();
}
Код:
for (int i=0; i< Server->Socket->ActiveConnections; i++) {
Server->Socket->Connections->SendText("user connected"); }
Server->Socket->Connections->SendText("user connected"); }
когда приходит месседж от юзверя на сервер свойство Server->OnRead обработчик по таому же типа посылает всем
Код:
for (int i=0; i< Server->Socket->ActiveConnections; i++) {
Server->Socket->Connections->SendText("Socket->RecievedText()");
}
Server->Socket->Connections->SendText("Socket->RecievedText()");
}
String MessageStr
в событии OnRead
Код:
При рассылке проверяй сколько данных ушло (SendText() возвращает для этого значение int байт)
если в какой-то канал данные не свалились -значит канал занят- жди событие OnWrite на этом канале и на нем делай до-отправку данных
для этого можно добавить в структуру булево значение NeedSend
тогда в событии OnWrite
делаешь так:
Код:
if(((MyStruct*)Socket->Data)-> NeedSend)
{
if(Socket->SendText(MessageStr)==MessageStr.Length())((MyStruct*)Socket->Data)-> NeedSend=false;
//сравниваем сколько ушло с размером сообщения, если совпадает- значит сбрасываем необходимость до-отправки
}
{
if(Socket->SendText(MessageStr)==MessageStr.Length())((MyStruct*)Socket->Data)-> NeedSend=false;
//сравниваем сколько ушло с размером сообщения, если совпадает- значит сбрасываем необходимость до-отправки
}
сделал как ты сказал и ничего. тоесть отправляется всем, но текст сообщения уходит только первому...проверял так- отсылал MessageStr+"чето-там" первому приходила "вся месягачето там" остальным просто чето-там...нипонемаю
нужно еше раз внимательно на код взглянуть...
мож где затираем MessageStr... может конфликт локальной и глобальной переменной...
может последовательность событий отследить нужно.. что за чем и в каком порядке происходит...
без кода не разобраться...
между присвоением MessageStr и отсылкой ничего не происходить значит затереть не могли...в атаче код, все полностью не вошло, по причине ограниченности аттача
MessageStr=Socket->ReceiveText();
в цикле, а данные из сокета нужно читать только один раз
Вот правильный вариант:
Код:
void __fastcall TForm1::ServerClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
MessageStr=Socket->ReceiveText();
for (int i=0; i<Server->Socket->ActiveConnections; i++)
{
// убрал строку чтения из цикла
Server->Socket->Connections->SendText(MessageStr);
Application->ProcessMessages();
}
}
TCustomWinSocket *Socket)
{
MessageStr=Socket->ReceiveText();
for (int i=0; i<Server->Socket->ActiveConnections; i++)
{
// убрал строку чтения из цикла
Server->Socket->Connections->SendText(MessageStr);
Application->ProcessMessages();
}
}
1-как можно перенаправить сообщение всем кроме приславшего его..
2-нормально ли будет если всё вешать на один порт? А если он занят?
3-еще чего-нить потом придумаю :)
Цитата:
Originally posted by BeOne
пасибо, теперь всё номано...но у меня еще вопросики есть, если можно то хотел бы получить ответ и на них...
1-как можно перенаправить сообщение всем кроме приславшего его..
2-нормально ли будет если всё вешать на один порт? А если он занят?
3-еще чего-нить потом придумаю :)
пасибо, теперь всё номано...но у меня еще вопросики есть, если можно то хотел бы получить ответ и на них...
1-как можно перенаправить сообщение всем кроме приславшего его..
2-нормально ли будет если всё вешать на один порт? А если он занят?
3-еще чего-нить потом придумаю :)
Я думаю что не стоит юзать эти компоенты для передачи данных лучше програмить winsocket, на больших объемах данных эти копоенты глючат по страшному.... это я точно говорю, проверено
Цитата:
Originally posted by vladsoft
Я думаю что не стоит юзать эти компоенты для передачи данных лучше програмить winsocket, на больших объемах данных эти копоенты глючат по страшному.... это я точно говорю, проверено
Я думаю что не стоит юзать эти компоенты для передачи данных лучше програмить winsocket, на больших объемах данных эти копоенты глючат по страшному.... это я точно говорю, проверено
к сожалению позно, прогаю для себя, а точнее надо это сдать по технологии програмирования, вот и стараюсь хоть что-то сделать...нас вообще бросили в огонь сказав сделайте нам вот это или это, а как сами должны уже знать не маленькие(2 курс).
(пока я там глюков не видел -кроме тех , которые вызваны непониманием программистом принципа их работы :) )
на этих компонентах у меня написан прокси-сервер для нашего офиса и вроде пока работает на любых обьемех данных (всего за месяц перекачиваем ок. 2 Гб траффика через эти компоненты... )
Либо сравнивай Ip адрес либо Handle сокетов
Код:
void __fastcall TForm1::ServerClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
MessageStr=Socket->ReceiveText();
for (int i=0; i<Server->Socket->ActiveConnections; i++)
{
if(Socket->RemoteAddress==Server->Socket->Connections->RemoteAddress) continue;
Server->Socket->Connections->SendText(MessageStr);
Application->ProcessMessages();
}
}
TCustomWinSocket *Socket)
{
MessageStr=Socket->ReceiveText();
for (int i=0; i<Server->Socket->ActiveConnections; i++)
{
if(Socket->RemoteAddress==Server->Socket->Connections->RemoteAddress) continue;
Server->Socket->Connections->SendText(MessageStr);
Application->ProcessMessages();
}
}
2-нормально ли будет если всё вешать на один порт? А если он занят?
все будет нормально -работает в асинхронном режиме.. если только 10 000 пользователей не наберется.... :) тогда надо будет уже писать по-взрослому... без компонентов - либо на чистом
WinSock либо на уровне драйвера сетевой катрты.
Цитата:
Originally posted by ART-CODE
Уважаемый vladsoft, пожалуйста опишите конкретно, какие именно глюки Вы там обнаружили
(пока я там глюков не видел -кроме тех , которые вызваны непониманием программистом принципа их работы :) )
на этих компонентах у меня написан прокси-сервер для нашего офиса и вроде пока работает на любых обьемех данных (всего за месяц перекачиваем ок. 2 Гб траффика через эти компоненты... )
Уважаемый vladsoft, пожалуйста опишите конкретно, какие именно глюки Вы там обнаружили
(пока я там глюков не видел -кроме тех , которые вызваны непониманием программистом принципа их работы :) )
на этих компонентах у меня написан прокси-сервер для нашего офиса и вроде пока работает на любых обьемех данных (всего за месяц перекачиваем ок. 2 Гб траффика через эти компоненты... )
упс. прикольная постановочка хорошо лови глюки
1 на одном ip может сидеть один клиент
2 невозможно определить процесс получения данных клиентов
3 при посылке потока теряется заголовочный файл
это так коротко...
art code если не влом пришли что ты соорудил может мы нет там копаем или что-то не там делаем...
1 на одном ip может сидеть один клиент
Почему ?
Что есть "клиент" ?
Компьютер, пользователь, программа ?
Что есть "Сидеть" ?
Вообще при подсоединении "клиента" можно его авторизовать (любым способом) а затем
в структуру засунуть индекс авторизациии
(см. советы выше про идентификацию соединения
при прмощи структуры в свойтстве Socket->Data)
когда работает прокси-сервер, то он выполняет от одного "клиента" одновременно несколько соединений с серверами интернет(получение/отправка почты,целый день висит для ICQ соединеие по SSL,запросы к сайтам WEB - одна страница загружается в среднем в 5-15 одновременных соединений)
2 невозможно процесс получения данных клиентов
Опять не понял:
"определить процесс получения данных клиентов" ???
ОТ клиентов или ДЛЯ клиентов и что значит Определить - это как ?
3 при посылке потока теряется заголовочный файл
Это про SendStream ?
так я им не пользуюсь, поэтому не знаю
вся пересылка у меня идет через буферы...
В СЛУЧАЯХ ПОТЕРИ ДАННЫХ:
1 - При рассылке проверяй сколько данных ушло
-см. выше. там написано...
2 - Прикол -
событие OnDisconnect - уведомляет нас не только о том, что произошло отключение, но и о том, что из сокета НУЖНО попытаться ПОЛУЧИТЬ данные !
Поэтому здесь запускаем бесконечный цикл
Код:
int ResLen=0;
char *rb=NULL;
do
{
ResLen=0;
ResLen=Socket->ReceiveLength();
if(ResLen > 0){
if(rb!=NULL)
{
delete[] rb;
rb=NULL;
}
rb =new char[ResLen];
Socket->ReceiveBuf(rb,ResLen);
// что-то делаем с буфером (либо его кому-то отсылаем либо где-то храним)
}
}while(ResLen!=0);
char *rb=NULL;
do
{
ResLen=0;
ResLen=Socket->ReceiveLength();
if(ResLen > 0){
if(rb!=NULL)
{
delete[] rb;
rb=NULL;
}
rb =new char[ResLen];
Socket->ReceiveBuf(rb,ResLen);
// что-то делаем с буфером (либо его кому-то отсылаем либо где-то храним)
}
}while(ResLen!=0);
3 - Вызов метода Socket->Close();
не гарантирует, что после этого в компоненте не произойдут события ..на пример OnRead
тогда нужно обрабатывать эти события несколько иначе (т. к. пришедшие данные нам уже не нужны)
Вообще после вызова этого метода лучше всего считать сокет закрытым не ранее, чем через 4 минуты...
art code если не влом пришли что ты соорудил
Не жалко, но стыдно - сыроват код, когда подправлю все для красоты тогда мож..., где -то что-то определю как класс... где-то - оптимизирую работу с памятью ( пока жрет больше, чем мог-бы)
вобщем не ранее, чем через месяц на моем сайте будет (сейчас думаю какое имя для него зарегистрировать...)
А пока это 3270 строк кода и почти без комментариев - голову сломаешь... :)
всем спасибо, сдал...теперь ухожу в сессию с головой :)