Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Delphi и сети

Войти
Регистрация
Восстановить пароль
 
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
#1

Delphi socket - Delphi

15.11.2016, 18:56. Просмотров 414. Ответов 14
Метки нет (Все метки)

Доброго времени суток, делаю курсовую работу по программированию, делаю чат (для студентов) вообщем сами сообщения (сигнал о том что они появились) на все IP адреса студентов которые в сети (у кого запущена программа) отправляет PHP скрипт UDP запрос
PHP
1
2
3
4
5
6
7
8
9
{
$timeout=0;
$errno = $errstr = null;
$server_info = "udp://1.1.1.1"; //писал на прямую мой IP (для теста)
$pack1='test_msg_from_udp_packet';
$fp = fsockopen($server_info,6729, $errno, $errstr, $timeout); //port к которому привязан сокет
socket_set_timeout ($fp, 1, 0);
fwrite($fp, $pack1);
} //сам скрипт php рабочий, ибо таким же макаром я делаю getstatus запрос с игровых серверов
Вот сам сокет на Delphi:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
type
    TPacket = packed record
    mode: byte;
    pack: array [0 .. 9999] of Char;
    public
    procedure InitUDP;
  end;
 
  var
  TUdp:TPacket;
  Sock: TSocket;
  ServerAddr: TSockAddrIn;
  wData: TWSAData;
 
implementation
 
procedure ExecutePacket(pack: TPacket{сам пакет};
from: AnsiString);
begin
  ShowMessage(pack.pack); //проверка работает ли сокет
end;
procedure RecvProc(Param: Pointer); stdcall;
var
  Count: LongInt;
  from: TSockAddrIn;
  FromLen: LongInt;
  Packet: TPacket;
  i, j: LongInt;
begin
  while True do
  begin
    FromLen := SizeOf(from);
    Count := recvfrom(Sock, Packet, SizeOf(Packet), 0, from, FromLen);
    if Count > 0 then
    begin
      ExecutePacket(Packet{сам пакет},
         string(inet_ntoa(from.sin_addr)));
    end;
  end;
end;
function SelfIp :string; //эта функция возвращает мой внутренний ИП: 192.168.0.5
const WSVer = $101;
var
  wsaData: TWSAData;
  P: PHostEnt;
  Buf: array [0..127] of Char;
begin
  Result := '';
  if WSAStartup(WSVer, wsaData) = 0 then
  begin
    if GetHostName(@Buf, 128) = 0 then
    begin
      P := GetHostByName(@Buf);
      if P <> nil then Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
    end;
    WSACleanup;
  end;
end;
procedure TPacket.InitUDP;
begin
  WSAStartup($0101, wData);
  Sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // SOCK_DGRAM означает,
  // что мы будем работать с транспортным протоколом UDP
  ServerAddr.sin_family := AF_INET;
  //ServerAddr.sin_addr.S_addr:=Inet_Addr('1.1.1.1'); //и так и сяк пробовал (тут мой ип был)
  ServerAddr.sin_addr.S_addr := INADDR_ANY;
  ServerAddr.sin_port := htons(6729);
  bind(Sock, ServerAddr, SizeOf(ServerAddr));
  CreateThread(nil, 0, @RecvProc, nil, 0, LongWord(nil^));
end;
end.
Сам сокет рабочий, проверял через Packet sender,но работает он тогда когда sin_adder.S_addr:=INDDR_ANY и отправляю UDP пакет на localhost (если указываю свой ип, то не какого результата) пробовал и свой ип указывать - толку 0
У меня стоит РОУТЕР (маршрутизатор) и подключение по локальной сети? Как мне сделать сокет чтобы он был доступен "извне"
Заранее спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.11.2016, 18:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Delphi socket (Delphi):

Delphi socket - Delphi
Всем добрый день,вот столкнулся с проблеммой есть клиент и сервер клиент будет работать постоянно (в автозагрузке)а сервер будут вкл и...

Delphi - Socket (Лобби) - Delphi
Здравствуйте! Такая ситуация, мне нужно всех пользователей распихать в беседу по три человека. Чтобы те сообщения которые отправляют они...

Delphi 7 ClienSocket.Socket.SendText(Edt2), отправка текста на сервер с заданным шрифтом - Delphi
Доброго времени суток, вопрос не корректен так как, я новичок, лишь 3 или 4 раз включаю Delphi 7, создал программу Чат и к ней сервер,...

Потеря соединения TClient Socket - TServer Socket - Delphi
После коннекта клиента к серверу минут 20 соединение живёт и клиенты получают сообщения через длительное время они перестают получать...

Ошибка: Socket Error #11001 или socket error #10051 - Delphi
Делаю простую проверку подключен к нету комп или нет procedure TForm1.Button1Click(Sender: TObject); var Connected: Boolean; ...

Socket Close - Delphi
помогите решить. нужно чтобы если received от get запроса больше 500кб, то происходил socket.close как реализовать? Добавлено через...

14
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
16.11.2016, 03:55 #2
Вам нужен "белый" айпишник. На роутере прописываете форвардинг порта, когда любая информация пришедшая по определенному протоколу и на определённый порт внешнего интерфейса роутера сразу же пересылается на внутренний айпишник на указанный порт.
0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
16.11.2016, 14:37  [ТС] #3
Прошу прощения за тупизм) Если я получу заветный "белый" IP, моя проблема исчезнет? (сейчас у меня статический IP - не меняется)
Моя программа будет работать на нескольких компьютерах, то есть 5 компьютеров клиентов должны иметь возможность общения через онлайн-чат между собой.
P.S: может подскажете альтернативное решение моей задачи? (Получение ответа с сервера (без сокета)) (Сервер - php скрипт)
0
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
16.11.2016, 14:51 #4
Видите ли, статичный - это не всегда "белый". Пусть вас по этому айпишнику попингуют те самые 5 клипов. И я правильно понимаю, что статичный айпишник на роутере, а не на ПК? В пхп не силён, а вот для Делфи задача тривиальная. Вы принципиально винапи используете или инструмент вам не принципиален?
0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
16.11.2016, 16:27  [ТС] #5
А как же реализованы сокеты например в онлайн играх? (Там тоже UDP и не важно какой у тебя IP) Я понимаю что возможно и при этом пишут они это на более функциональных и "мощных" языках.
Если у вас есть любой другой способ, я не против попытаться мне не принципиально.
0
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
16.11.2016, 17:22 #6
Не совсем корректное сравнение. У онлайн игр как раз белый айпишник (если не выдаваться в тонкости), по нему и связываются. Языки тут ни при чем, это относится к компьютерным сетям и маршрутизации.
0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
16.11.2016, 18:37  [ТС] #7
Как же мне тогда быть?
0
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
17.11.2016, 06:07 #8
Видите ли, решения проблемы есть, и не одно, вот только вам надо задуматься: а стоит ли оно того? Вот вы делаете чат для студентов в качестве курсовой. Как я понимаю, вы не собираетесь его использовать в дальнейшем и продвигать в массы? Тогда зачем вам заморачиваться, собственно? Берете, проводите отладку целиком локально, на своем компьютере (это вы уже умеете, подключение к localhost решает все текущие проблемы на этапе разработки). Да, при работе через интернет могут вылезти некоторые баги из-за потерь пакетов, но даже работу в локальной сети можно считать надежной и брать за аксиому, что потерь пакетов наблюдаться не будет.

Поэтому, разрабатываете чат, отлаживаете его локально. Потом создаете условия для тестирования в локальной сети: приглашаете знакомых с ноутбуками, например, и соединяетесь через ваши айпишники.

В любом случае, у вас всегда есть альтернативный вариант: вы можете заплатить немного денег и разместить серверную часть (а он у вас ведь базируется на php) на каком-нибудь хостинге. В результате у вас всегда будет доступ к своему скрипту через белый айпишник. Что еще надо?

Не по теме:

Для меня несколько странно использования php для этих целей, как и выбор протокола UDP, конечно, но я считаю, что у вас было достаточно причин для выбора именно такого решения. Я бы не заморачивался и делал все на TCP/IP по многим причинам, но выбор ваш.

0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
17.11.2016, 16:13  [ТС] #9
У меня есть хостинг (VDS - виртуальный сервер) на нем и работает тот самый php скрипт-сервер, и отправляю я на свой IP, но сокет не "ловит" мои посыл. Этой программой будут пользоваться, минимум 2-3 человека (5 человек - это как пример), помимо чата там будет расписание для групп, контактные данные студентов (личные номера телефонов, телефоны представителей)+ ближайшие события (групповые походы в кино, экзамены и прочее)
p.s: мне не дает покоя мысль, как же устроены мультиплеер игры (например call of duty 2: ведь она у меня идет без проблем, а там тоже UDP).
0
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
17.11.2016, 16:57 #10
Там все просто. Вы сказку про Гензеля и Гретхен читали? Вот и ваш пакет так же действует (если грубо и не выдаваться в детали). Он идёт к серверу, находит его, а обратный путь уже известен. Серверу остаётся лишь ответить на этот пакет и он доберётся до адресата даже не зная его конечного адреса. Поэтому все, что надо серверу стрелялки - белый айпишник, а обратные пути пакеты сами найдут (конечно не сами и не найдут, а их направят, но вам это ни к чему).

Ваш скрипт не должен ничего отправлять - для сервера на UDP это абсурдно. Он должен только отвечать. Отправлять может TCP сервер из-за наличия того самого сокета ("туннеля" от клиента к серверу), которого у UDP нет. Поэтому я вижу только такой вариант: ваш клиент опрашивает сервер об изменениях каждую секунду, а сервер отвечает есть ли эти изменения и какие они.
0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
17.11.2016, 17:22  [ТС] #11
Запросы к серверу осуществляю через http элементы то есть: site.ru/StudentClient/main.php?type=login&login=root&pass=rootpass
на что php скрипт выводит yes, no (в зависимости от введенных данных (логина и пароля))
Чат я планировал сделать так:
site.ru/StudentClient/main.php?type=sendmsg&login=root&pass=rootpass&text=всем привет
В ответ сервер должен отправить всем клиента (на все их IP) которые авторизовались и сейчас онлайн (я их мониторю) UDP пакет с текстом сообщения, на что Delphi должен его "поймать" и добавить соответствующий элемент в ListBox
0
Nanotentacle
252 / 135 / 41
Регистрация: 20.10.2016
Сообщений: 733
18.11.2016, 03:43 #12
Вот почему бы при переходе по ссылке на отправку сообщения вам само сообщение не запихать в БД (а вы ведь с БД работает?) и не транслировать потом по запросу? Я вам ещё раз повторю: рассылка UDP напрямую клиентам без их запроса настолько же абсурдна, как если бы веб-сервер сдал данные в ваш браузер самостоятельно, не ожидая от вас запроса с ссылкой.

Простой вопрос: как вы мониторите клиентов?
0
xeonz
580 / 109 / 17
Регистрация: 16.05.2014
Сообщений: 942
18.11.2016, 14:14 #13
Цитата Сообщение от Revo1tDamaGe Посмотреть сообщение
Чат я планировал сделать так:
site.ru/StudentClient/main.php?type=sendmsg&login=root&pass=rootpass&text=всем привет
В ответ сервер должен отправить всем клиента (на все их IP) которые авторизовались и сейчас онлайн (я их мониторю) UDP пакет с текстом сообщения,
В таком случае если ваш клиент находится за NAT, вам придется делать проброс порта на роутере. Оно вам надо? Зачем завставлять пользователя чата для подключения к серверу и корректного приема сообщений заставлять делать проброс портов? Более того, если NAT делает провайдер, то сделать проброс портов может только провайдер и по понятным причинам провайдер такими вещами не горит желанием заниматься.

Опять таки, если вам интересно, как эту проблему обходят приложения, использующие UDP, то это целая обширная тема, которая называется "обход NAT" (UDP NAT traversal), здесь же рядом стоят такие штуки как STUN. И явно она (тема с UDP) вам сейчас не нужна.

Добавлено через 6 минут
Как вариант делать сервер на белом адресе, принимающим UDP пакеты от клиентов и направляющим им ответ. Но опять таки, вам это лучше не делать, потому что UDP не контролирует доставку пакетов, вы на реальных сетях за пределами локалки, получите потери данных. Чтобы их не было, вам нужно писать протокол контроля передачи пакетов. Оно вам надо?

Чтобы писать работающие на реальных сетях за пределами локалки, и работающие хотя бы более менее сносно, сетевые приложения с использованием чего то более сложного, чем банальный HTTP(s), нужно хотя бы немного вникнуть в тему сетей и передачи пакетов, в протоколы TCP и UDP, в NAT. Тогда вам все эти сокеты станут сразу понятными и все вопросы уйдут.
0
Revo1tDamaGe
0 / 0 / 0
Регистрация: 25.05.2015
Сообщений: 17
18.11.2016, 17:04  [ТС] #14
То есть мне ставить грубо говоря цикл в котором будут постоянные запросы к серверу на наличие новых сообщений, и если такие имеются то отображать их?
0
xeonz
580 / 109 / 17
Регистрация: 16.05.2014
Сообщений: 942
18.11.2016, 17:07 #15
Можете попробовать что то вроде:
https://habrahabr.ru/post/122783/
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2016, 17:07
Привет! Вот еще темы с ответами:

Socket адрес сервера - Delphi
Доброго времени суток. Сейчас пишу небольшой проектик на delphi, возникла проблемка. Приложение клиент-серверное, сервер уже готов (в...

Вопрос про socket... - Delphi
Доброго времени суток, написал чат на основе server/clientsocket, когда с клиента подключаюсь к серверу на самого себя же, то естественно...

Socket и отправка stringlist - Delphi
Всем привет :popcorn: Как мне перекинуть огромный (100-600 мб) stringlist серверу (самое тяжёлое:fie:), чтоб потом принятый текст можно...

Вопрос про Socket - Delphi
Сделал чат на основе Client/ServerSocket, клиентом пробую подключиться, и есть что то не так то пытатся долго но толку нет, как сделать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
18.11.2016, 17:07
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru