Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вопрос по теме TServerSocket

290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
Здраствуйте уважаемые форумчане.
Вопрос как я посмотрел по поиску обсуждался но решение было написано не по моей бяде, и на гугле нет ответа.

У меня создан Сервер и созданы клиенты,
но при подключение к серверу более обного клиента возникает проблема
первый подключившийся клиент получает индекс подключения 0, то есть
ServerSocket1->Socket->connections[o]
Второй клиент получает индекс 1 и т.д.

Вопрос в том как мне отправлять к примеру текст, конкретному клиенту.
416
27 ноября 2009 года
MaitreDesir
380 / / 02.01.2008
По вашей бяде можно написать вот так вот например.
Как вы вообще храните информацию о клиенте? Нельзя чтоли сделать массив (список) с экземплярами класса "TMyClient"? Массив представляет собой информацию обо всех клиентах, а в классе кроме прочего (например, ИД клиента в БД), хранить ссылку на соединение (или хотябы номер его). А добавлять в список клиента при его подключении.
А уж как отправить текст клиенту, зная соединение...
И разумеется, что "по поиску" и "на гугле" нет ответов - это настолько банально и понятно, что не стоит даже обсуждать.
290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
Дак вот и проблема то собственно в том что я немогу сохранить индекс клиента. Во первых при каждом подключение индеки меняется, то есть к примеру Клиент1 подключился к серверу он использует 0 индекс, затем подключился Клиент2 он использует 1 индекс, а потом к примеру Клиент1 отключился и подключился Клиент3 то в этом случае Клиент3 получит индекс 0. Вот в чем бяда.

P.S. А можно каждому клиенту назначить индекс покдлючения к серверу. Чтоб каждый клиент всегда подключался по одному и то муже индексу, а не так кто первый успел тот и к примеру на нулевом индексе.)))
416
27 ноября 2009 года
MaitreDesir
380 / / 02.01.2008
Прочитай еще раз что я тебе написал. У тебя когда клиент подключается ,ты вообще отличаешь как то клиента 1 от клиента 2? Если да - почему при ПОДКЛЮЧЕНИИ не можешь в (экземпляр класса!) клиента прописать соединение, по которому он подключился В ДАННОЙ СЕССИИ? Религия не позволяет?
Пример(аж не поленился):

Код:
Класс Клиент = (Соединение, Активен);

Массив[2] Клиенты;

Событие Подключен(Информация, н_соединения)
{
  Определяем что за клиент (номер_клиента)
  Клиенты[номер_клиента].соединение = н_соединения;
  Клиенты[номер_клиента].Активен = Да;
}

Событие Отключение(Информация, н_соединения)
{
  Находим номер_клиента с Клиенты[номер_клиента].Соединение=н_соединения и
  Клиенты[номер_клиента].Соединение=-1
  Клиенты[номер_клиента].Активен= Нет
}

Функция ОтправитьСообщение(Текст, номер_клиента)
{
Если Клиенты[номер_клиента].Активен То
  Через сокет через соединение Клиенты[номер_клиента].Соединение отправляем текст
Иначе
  Ошибка!
}
288
27 ноября 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: Patr1ot
Дак вот и проблема то собственно в том что я немогу сохранить индекс клиента. Во первых при каждом подключение индеки меняется, то есть к примеру Клиент1 подключился к серверу он использует 0 индекс, затем подключился Клиент2 он использует 1 индекс, а потом к примеру Клиент1 отключился и подключился Клиент3 то в этом случае Клиент3 получит индекс 0. Вот в чем бяда.



Все равно не вижу проблемы. Зачем настолько жестко привязываться к индексу соединения. Просто считайте, что пока клиент подключен - индекс валиден, как только отключается (вы получите OnClientDisconnect или OnClientError) индекс становится невалидным и вы просто "забываете" о существовании этого клиента.

290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
Тогда встречный вопрос а как я могу их отличить?

К примеру как вы сказали номер клиента, этот номер должен быть прописан в клиенте или при подключение например текстом отправляет свой номер?

Немного недопонимаю...:o

Вернее у меня есть список с номерами клиентов, то есть сервер скажем может проверять тот или не тот клиент, а самих клиентов я как проверить смогу, ведь у них ничего при подключение не изменяется.
То есть они идентичны друг другу.
416
27 ноября 2009 года
MaitreDesir
380 / / 02.01.2008
Цитата: Patr1ot
Тогда встречный вопрос а как я могу их отличить?

К примеру как вы сказали номер клиента, этот номер должен быть прописан в клиенте или при подключение например текстом отправляет свой номер?

Немного недопонимаю...:o



Нет, ну уж извините, чем у вас клиенты отличаются я понятия не имею! Может быть бубликами? А может ФИО? А может mac-адрес? Откуда на форуме могут знать, как идентифицировать ваших клиентоф.
Пфффф.... пар выпустил...
Процедура идентификации клиента по передаваемым им известным ему данным называется аутентификация. Также ее иногда ставят в ряд с авторизацией. По ссылкам найдете объяснение что есть что и как это делают.

290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
Ну вообще я делаю у клиентов идентификацию по IP - адресу, то есть
при запуске клиент программно определяет IP-адрес клиента, к примеру
10.0.4.1 после чего мы отсеиваем, а можем и не отсеивать так даж лучше
получаем идентификационный код клиента.

Я просто немогу немного понять клиент должен отправить на сервер текст
с номером индентификационным кодом, или как то подругому.

Но фишка то в чем:

К примеру клиент подключается к серверу, и отправляет текст с кодом идентификации 10.0.4.1 , затем сервер это понятно получает и сверяет соединение, но мне непонятно как на сервере сохранить индекс именно этого клиента, какой командой можно получить индекс именно этого клинта, ведь для отправки текста тому же клиенту мы должны будем указать номер индекса. то есть

ServerSocket1->socket->Connections[н_индекса]->SendText;

вот именно н_индекса как запихать в переменную?
Естественно чтобы потом использовать для передачи информации именно этому клиенту в текущей сессии.
1
27 ноября 2009 года
kot_
7.3K / / 20.01.2000
Я бы не рекомендовал использовать TServerSocket. Глюкавый.

Код:
void __fastcall TfmMain::ssServerClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
 for(int i=0;i<ssServer->Socket->ActiveConnections;i++){
  if(ssServer->Socket->Connections==Socket){
   Command = ssServer->Socket->Connections->ReceiveText();
   Station = Command.SubString(Command.LastDelimiter("#")+1,Command.Length());
   ConnectionList->Add(Station);
   ssServer->Socket->Connections[ConnectionList->IndexOf(Station)]->SendText("Connected");
    mmLog->Lines->Add(DateTimeToStr(Now())+"\t&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; &#65533;&#65533;&#65533;&#65533;&#65533;&#65533;   -\t "+Station);
    mmLog->Lines->Add(DateTimeToStr(Now())+"\t&#65533;&#65533;&#65533;&#65533;&#65533; &#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;   -\t "+IntToStr(ConnectionList->Count));
  }
 }
}

делается так.
На лишние не обращай внимание - это просто кусок кода. А это чтение команд клиента:
Код:
void __fastcall TfmMain::ssServerClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
   AnsiString TempCommand;
 for(int i=0;i< ssServer->Socket->ActiveConnections;i++){
  if(ssServer->Socket->Connections==Socket){
  Command = ssServer->Socket->Connections->ReceiveText();
   Station = Command.SubString(Command.LastDelimiter("#")+1,Command.Length());

   Command = Command.Delete(Command.LastDelimiter("#"),Command.Length());
   TempCommand = Command.SubString(1,Command.LastDelimiter("#")-1);
   mmLog->Lines->Add(DateTimeToStr(Now())+"\t&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; &#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;\t"+Command+"\t&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;\t"+Station);

  if(TempCommand == "Send"){
    Filename = edInStation->Text+"\\"+Command.SubString(Command.Pos("#")+1,Command.Length());
    acSendFiles->Execute();
    }
   else if(TempCommand == "Receive"){
    Filename = edOutStation->Text+"\\"+Station;
    acReceivFiles->Execute();
   }
   else if(TempCommand == "Connect"){
   }
  }
 }
}

Код писался крайне давно и вытащен из какогото древнего бекапа - вполне может содержать ошибки и неудачные решения.
1
27 ноября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Patr1ot

Я просто немогу немного понять клиент должен отправить на сервер текст
с номером индентификационным кодом, или как то подругому.

Но фишка то в чем:

К примеру клиент подключается к серверу, и отправляет текст с кодом идентификации 10.0.4.1 , затем сервер это понятно получает и сверяет соединение


прочти основы сетевого программирования - откроешь для себе много нового. Клиенту не нужно отправлять строку с идентификатором.

290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
Спасибо Kot_ Но блин не вяжется.

Цитата:

Kot_
Я бы не рекомендовал использовать TServerSocket. Глюкавый.



А чем лучше воспользоваться?

Еще проблема с сокетами в том, что ситуация:

На сервер подключилось 3 клиента.

к примеру по очереди:

Клиент1 - 0(индекс)
Клиент2 - 1(индекс)
Клиент3 - 2(индекс)

При коннекте всех трех клиентов индексы мы запомнили, но к примеру отключается Клиент1, вместо него подключается Клиент4,и становится вообще бордак:confused:

Клиент2 - 0(индекс)
Клиент3 - 1(индекс)
Клиент4 - 2(индекс)

И в итоге если у нас сохранено что клиент2 подключен к 1(индексу) , мы начинаем ему передавать текст или поток, то этот текст или поток получит клиент3. Это не есть хорошо. Какойнибудь пользователь подключисля и вместо того чтобы например отправить комуто файл, сам фигзнает откуда его получает :D

Это же нелепость просто.
Ведь можно както или может через какой другой компонент вместо TServerSocket&TClientSocket организовать нормальную работу.

Чтоб если пользователь1 отправил запрос на скачивание файла, то пользователь1 и получил этот файл.

290
27 ноября 2009 года
Patr1ot
458 / / 09.02.2008
А где найти об этом литературу?
1
27 ноября 2009 года
kot_
7.3K / / 20.01.2000
Я же показал как идентифицируется клиент. в чем проблема то?
Во вторых - соединения клиента лучше вообще обрабатывать в отдельном потоке - тогда просто отпадает необходимость в переборе соединений и определении клиентов - хотя значительно усложняется код.
В третьих - вопрос "где найти литературу" должен возникнуть задолго до того, как сообщение появилось на форуме. Если же не так - то тогда надо заканчивать писать фигню на форум - а найти литературу, прочесть, а затем задавать вопросы.
Литература находится в ближайшем книжном магазине либо в сети.
48K
27 ноября 2009 года
Save.L
18 / / 18.09.2009
С помощью этих компонентом стандартными методами реализовать вашу задачу не получится - переходите на Indy.

Хотя можете еще так попробовать:
Вот вы хотите определенному клиенту что-то отправить. Да? Тогда:
1. "Гавкните" всем подключенным клиентам чтоб они вам прислали свой идентификатор (допустим ip адрес).
 
Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  AnsiString gav = "Ты кто?";
  for(int i=0; i<ServerSocket1->Socket->ActiveConnections; i++){
       ServerSocket1->Socket->Connections->SendText("gav");
  }
}


2. На стороне клиента:
 
Код:
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
   AnsiString str = Socket->ReceiveText();
   if (str == "Ты кто?"){
      //О, нет!?!?..Они хотят знать мое имя!
      ClientSocket1->Socket->SendText("192.168.1.34");
   }
}


3. на стороне сервера проверяем:
Код:
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
  AnsiString s;
  s = Socket->ReceiveText();

  //ищем нашего клиента
  if (s == "192.168.1.34"){
        //вау! вот он. Шлем ему наше писмеЦо
        Socket->SendText("Мы знаем что ТЫ делал прошлым летом!");
  }
}


код так придумал - не проверял.
ну и естественно нужно пользоваться разделителями, как было предложено уважаемым kot_
1
27 ноября 2009 года
kot_
7.3K / / 20.01.2000
Обїясните мне идиоту зачем вы шлете ип-адреса идентификатары и пр.? Не лучше ли всеже дать себе труд прочесть хоть что нибудь по теме и не придумывать всякую фигню - ГОСПОДА ИНДУСЫ?
48K
27 ноября 2009 года
Save.L
18 / / 18.09.2009
Цитата: kot_
Обїясните мне идиоту зачем вы шлете ип-адреса идентификатары и пр.? Не лучше ли всеже дать себе труд прочесть хоть что нибудь по теме и не придумывать всякую фигню - ГОСПОДА ИНДУСЫ?

это всего лишь предложение. Ну хотя и сознаюсь - не в курсе как подругому. Я пользую Indy.
А может вкратце объясните...? то что вы написали выше по сути тоже самое.

416
27 ноября 2009 года
MaitreDesir
380 / / 02.01.2008
По сути, не по сути...
Книжку хоть одну откройте! Статьи почитайте. Инди это инди, но если Вы не знаете основные принципы работы этих инди, то будете выдовать индусский код. kot_ прав абсолютно, надо книжки читать прежде чем вопросы задавать.
1
27 ноября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Save.L
это всего лишь предложение. Ну хотя и сознаюсь - не в курсе как подругому. Я пользую Indy.
А может вкратце объясните...? то что вы написали выше по сути тоже самое.


Если вкратце - то вся необходимая информация у вас есть. Вам не нужно отправлять IP адрес серверу и т.п. - в момент установки соединения все это уже есть. Т.е.:

 
Код:
ClientSocket1->Socket->SendText("192.168.1.34");

практически тоже самое что и знаменитый индусский код
 
Код:
String Bool = "false";
if(Bool.Length() ==5){
//
}

И говорит о том что вы очень далеки от понимания основ сетевого программирования.
53K
04 декабря 2009 года
Pala4
10 / / 30.11.2009
Напишу более понятный код

Код:
Событие SSocketClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
   AnsiString IPClient;
   for (int i=0;i<SSocket->Socket->ActiveConnections;i++)
      {
      IPClient=SSocket->Socket->Connections->RemoteAddress; // Получение IP клиента
     if (Memo2->Lines->Strings==IPClient)
         {
         ShowMessage("IP: " + IPClient + " уже зарегестрирован");
         break;
         }
     else
         Memo2->Lines->Strings=IPClient; // Заносим IP клиента в Мемо
         Memo1->Lines->Add("Клиент присоединился");
      }
}

т.е. как уже говорилось выше "Зачем изобретать велосипед?", придумывать идентификаторы, когда можно использовать IP адрес, находящийся в сокете. Чтобы лучше разобраться с работой сокетов можно написать чат пользуясь WSASocket
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог