![]() |
|
Модераторы: Snowy, Poseidon, MetalFan |
![]()
|
|
| OXOTHUK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
Как подсоединить сервера и клиента через интернет(У сервера фиксированный IP). У мня чтобы я ни писал в поле Adress, какой бы IP не вводил, всё равно не хочет коннектится.
ЗЫ если есть более удобные/легко осваиваемые способы прередачи record'а через интернет, то скажите, желательно с примером. |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
Отладь сначала на одной машине.
Если там будет работать, значит проблемы на другом уровне. |
|||
|
||||
| OXOTHUK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
на одной машине работает, даже если вводить бурду в адрес.
А какие могут быть проблемы? |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
||||
|
||||
| OXOTHUK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
Но работает. Запускаю сервер, клиенту пишу адрес "asdfga", нажимаю актив и сенд, и у сервера появляется. (на одной машине, подозреваю, что если он не может найти адрес, то ищет на 127.0.0.1). А вот через интернет не работает, файрволы пускают прогу. А может это быть если порт занят другой прогой? ЗЫ а как надо называть Host-свойство у клиента? а то у мня не всегда подключается, иногда говорит, что еррор сокет 10060.(хотя я не этим сокетом пользуюсь) Но если изменить имя хоста, то всё нормально. |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
Если ты прописал asdfga, а законнетилось на локальный, значит нифига ты не прописал. Значит где-то ошибка, и твоё asdfga не играет никакой роли. Это не сокет, а код ошибки. Вбей его в гугль - сразу найдёшь, что она значит. |
|||
|
||||
| OXOTHUK |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
Ну что тут может быть не так? |
||||
|
|||||
| misha_mike |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 1.6.2007 Репутация: 1 Всего: 1 |
Во-первых я что-то не вижу чтобы ты порт указал. А во-вторых используй свойство Host.
А вот это излишество:
Достаточно только FormDestroy. И тут поосторожней:
Никто не гарантирует что на приемной стороне твоя структура прийдет целиком а не парой-тройкой кусочков последовательно (и чем больше твоя структура и чем медленнее канал тем больше вероятность ее разрыва, а начиная с нескольких килобайт размера разрываться она будет гарантированно). Также никто не гарантирует что два (или больше) последовательных SendBuf(...) небольшого размера приведут к генерации соответствующего количества событий OnRead на приемной стороне, а не слипнуться в один кусок. Это сообщение отредактировал(а) misha_mike - 8.6.2007, 16:15 |
||||
|
|||||
| OXOTHUK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
misha_mike,
порт указан в изначальных настройках, которые на обжект инспекторе. АПД: Сам допёр, спосебо всем. Это сообщение отредактировал(а) OXOTHUK - 8.6.2007, 16:14 |
|||
|
||||
| OXOTHUK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
Нозникла новая проблема: как передать такую струкруру:
Через SendBuf естесна не передаётся, но я попробывал сохранить в файл, а потом SendStream. Но получать приходится через RecieveBuf. И опять не доходит или что ещё. Есть какие-нибудь способы? ЗЫ на одной машине всё нормально передаётся |
|||
|
||||
| misha_mike |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 1.6.2007 Репутация: 1 Всего: 1 |
Как не передается? Какую ошибку возвращает? Вообще для передачи больших блоков (более 2 килобайт) надо их нарезать на кусочки по одному-два килобайта, и передвать по кусочку пока не возникнет ошибка WSAEWOULDBLOCK. Потом ждать события OnWrite и повторять с места остановки до следующей ошибки. И так далее до конца буфера. Приходить она тоже будет кусками, причем совсем не обязательно такими, которыми ты ее нарезал при передаче, поэтому о сборе в единое целое тоже нужно позаботиться на приемной стороне.
P.S. А связь с localhost всегда более дубовая чем с удаленной машиной, много подобных ньюансов не вылазят потому что при связи с самим собой стек TCP/IP может работать далеко не на всю свою глубину.... P.P.S. А вообще такие вещи по сети лучше не гонять, и вместо крайне избыточной структуры с COUNT-ом перегони сначала COUNT, а потом соотвествующее количество неизбыточных структур такого вида (и обрати внимание на слово packed):
А не то тебя юзера проклянут. Это сообщение отредактировал(а) misha_mike - 10.6.2007, 16:34 |
|||
|
||||
| OXOTHUK |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
никакую, там просто не возникает события OnRead. а чем отличается packed record от record? :lamo: Но вроде работает. АПД только не всегда доходит. вот серверная:
вот клиентская:
или можно как-то лучше реализовать? :lamo: я с сетями никогда не работал Это сообщение отредактировал(а) OXOTHUK - 10.6.2007, 18:47 |
||||
|
|||||
| misha_mike |
|
||||||||||||||||
|
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 1.6.2007 Репутация: 1 Всего: 1 |
И OnError не возникает? Не может этого быть...
Тем что выравнивания нет и структура имеет именно такой размер, который имеют в сумме ее члены. В прочем об этом написано в любом учебнике и к сетям отношения не имеет.
Что такое АПД?
Не передавай без крайней необходимости числа в виде текста, это кроме того что избыточно, в случае вещественных чисел обязательно приведет к проблемам. Пиши Socket.Send(count_msg, SizeOf(count_msg)), а на приемной стороне соответственно Socket.ReceiveBuf(count_msg, SizeOf(count_msg)), но ты про это пока забудь и читай дальше.
Я же предупреждал, что так делать нельзя никогда. Никто не гарантирует что все что ты передал с одной стороны прийдет на другую именно так как ты ожидаешь. Во-первых рано или поздно случится так что в твой ClientRead прийдет count и три с половиной msg, а оставшиеся пять с половиной -- в следующем ClientRead, который совершенно не готов к такому повороту (не разобравшись в том что пришло, сразу читает Count и что-то там принимает). Во вторых очень бысто случится так, что в одном ClientRead прийдет то что ты передал в два или три захода! В первом случае ты получишь ошибку, а во втором просто проворонишь один или несколько пакетов. Еще раз поясняю, прочитай очень внимательно. Со стопроцентной вероятностью ты столкнешся с такими ситуациями: 1. Разрезание. ПЕРЕДАТЧИК: Вызываешь Socket.SendBuf(Data, 6000); ПРИЕМНИК: Возникает событие ClientRead, в котором Socket.ReceiveLength = 4096, и через некоторое время опять возникает событие ClientRead, в котором Socket.ReceiveLength = 1904. РЕЗЮМЕ: То что ты передал одним куском, пришло несколькими. 2. Склеивание. ПЕРЕДАТЧИК: Вызываешь Socket.SendText('текст'), и через некоторое время Socket.SendBuf(Data, 8). ПРИЕМНИК: Возникает одно единственное событие ClientRead, в котором Socket.ReceiveLength = 13 (сумма длин текста и данных). РЕЗЮМЕ: То что ты передал несколькими Send-ами пришло одним куском. 3. Смешивание. ПЕРЕДАТЧИК: Вызываешь Socket.SendText('текст'), и через некоторое время Socket.SendBuf(Data, 6000). ПРИЕМНИК: Возникает событие ClientRead, в котором Socket.ReceiveLength = 4096 и в этот размер входит переданный первым Send-ом 'текст' и первые 4091 байт из буфера Data, переданного вторым Send-ом, и через некоторое время опять возникает событие ClientRead с оставшимися 1909 байтами из буфера Data, переданного вторым Send-ом. РЕЗЮМЕ: То, как ты передаешь данные никак не связанно с тем, как они прийдут. Сохраняется только последовательность, но никак не блочность. 4. Переполнение буфера передачи WinSock. ПЕРЕДАТЧИК: Вызываешь Socket.SendBuf(Data, 100000), тут же возникает OnError, в котором ErrorEvent = eeSend. ПРИЕМНИК: Ничего не приходит. РЕЗЮМЕ: Передавать в один присет более нескольких килобайт нельзя, нужно разрезать большой пакет на тесколько маленьких (не более пары килобайт) и передвать их до тех пор пока не возникнет OnError (при этом ErrorEvent должен быть равен eeSend, иначе прерываем передачу и генерируем ошибку разрыва канала связи). После этого нужно остановиться, дождаться события OnWrite и только тогда продолжить до следующего OnError. И так пока не закончатся данные для передачи.
Первый вариант -- реализовываешь свой протокол верхнего уровня, в котором на предающей стороне перед полезными данными помещается некоторая структура-заголовок, включающая размер передаваемого блока, а потом все это будет передаваться по кускам согласно п. 4. На приемной стороне эта структура анализируется и производится накопление пришедших данных до тех пор пока их объем не достигнет указанной в заголовке длины. Также если объем принятых данных превышает размер остатка текущего блока, нужно инициализировать начало приема следующего блока. Второй вариант -- воспользоваться оним из существующих протоколов верхнего уровня, например IRC. Благо соответствующих компонент достаточно. Это сообщение отредактировал(а) misha_mike - 10.6.2007, 20:15 |
||||||||||||||||
|
|||||||||||||||||
| OXOTHUK |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.9.2005 Репутация: нет Всего: 6 |
сам вызов функции не проверял, но видимых ошибок нет никаких. UPD - updated, т.е. исправил пост и дописал.
тут мня возникает несколько вопросов: 1) чем принимать, т.е. каким типом? array of byte? 2) как склеивать\разрезать получившиеся части?
TInIRCServer/TInIRC подойдёт с вкладки Indy? Или есть что-то лучше? А есть какой-нибудь мануал как или пользоваться, а то они не похожи на сокеты. Желательно с примерами. ЗЫ. Дельфийская справка у меня не работает. |
||||
|
|||||
| misha_mike |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 1.6.2007 Репутация: 1 Всего: 1 |
Блин, это же основы работы с "сырыми" данными. Без этого ничего сложнее калькулятора не написать, а ты сразу игрушки с мультиплеером ваять собрался... Принимать надо указателем на динамический блок, передавать им же. Динамические массивы конечно тоже сгодятся, но ты не на джаве и не в дотнете пишешь чтобы на них выезжать в любой ситуации. Как производится работа с динамической памятью написано в ЛЮБОМ учебнике по Паскалю. Указательную арифметику для нарезки/склейки пакетов имеет смысл показывать только поле того как подобные отквоченному вопросы возникать перестанут в принципе. А спрашивать об тривиальных операциях по извлечению подмассива и склеиванию нескольких динамических массивов вовсе должно быть стыдно!
Там примитив полнейший, да и не единственные это компоненты (и не единственный подходящий протокол).
Это не оправдание, либо чини либо вызывай ее руками. А основы языка (изложенные в любой книжке) рассказывать думаю тут желающих не много наберется. |
||||||
|
|||||||
![]()
|
| Правила форума "Delphi: Сети" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |