1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
|||||||||||
1 | |||||||||||
Server Socket, Asynchronous socket error 1005308.07.2014, 11:50. Показов 9067. Ответов 18
Метки нет (Все метки)
Всем привет. Сразу к делу. Работаю с компонентом ServerSocket, при приеме данных возникает asynchronous socket error 10053.
Сервер работает в режиме stNonBlocking, клиент - постоянно посылает какую-то информацию. Задача - принять и обработать. Интервал между посылками, примерно 20ms а размер пакета 150 байт.
Какие есть варианты? Быть может прописать что-то в OnClientError, помимо ErrorCode = 0.
0
|
08.07.2014, 11:50 | |
Ответы с готовыми решениями:
18
Asynchronous socket error 10060 Ошибка: Asynchronous socket error 10061 Server(Client)Socket Client и Server Socket |
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
||||||
08.07.2014, 17:41 [ТС] | 3 | |||||
Так Вектор в том-то и дело что сам наращивается и ему все равно какой длинны он будет, пока не займет в теории всю оперативную память компьютера.
Другое дело что массив в векторе в памяти идет как бы подряд и если какой-то участок памяти на его доблестном разрастании занят, то он переносит весь вектор в новый участок плюс резервирует место, при каждом наращивании все больше и больше. Проблема в том что как только клиент присоединяется, моментально вылетает ошибка или вовсе программа убивается виндой. Не понимаю почему так. Добавлено через 2 часа 21 минуту Попробовал стандартный чатик из Examples в builder. Все великолепно принимает, простой как палка.
Или использовать ReceiveText, загонять в string, а после уже разбивать как захочу? Но разве это из-за ReceiveBuf() запара? Или все-таки с вектором перемудрил?
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
|
09.07.2014, 10:21 | 5 |
Dinkin, прежде, чем ковыряться в коде, имеет смысл ознакомиться с самой ошибкой. 10053 означает "удалённый компьютер закрыл подключение". Из-за чего-то. Т.е., при попытке доступа к сокету, соединение уже разорвано. Думаю, надо смотреть клиента...
0
|
09.07.2014, 11:46 | 6 |
Так он же пишет, что при нормальной отправке данных все норм...а данная ошибка в основном распространяется на сервер, который закрывает соединение, если что-то не успел/не смог обработать по какой-либо причине.
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
||||||
09.07.2014, 12:03 | 7 | |||||
Dinkin, можешь, конечно, остаться при своих. А можешь показать код, как происходит отправка. Или хотя бы сделай предварительную проверку, активно ли подключение
0
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
||||||
10.07.2014, 11:03 [ТС] | 9 | |||||
Клиент, это плата, подсоединенная к чипу Withnet Ethernet W5100, она просто кидает connect и если сервер отвечает, начинает забрасывать данные. Дело в том что другая прога, которую я писал на Delphi, работает, хотя в builder'e сделал все аналогично, за исключением вектора. Там был статический буфер, набиваемый до конца, а после закрывающий соединение. И еще, как я понял Indy server работает в Thread blocking а Server socket в nonBlocking.
Теперь же задача стоит в том, что мы не знаем сколько будет данных, поэтому и вектор. Плата шлет огромное количество попыток connect() и как только получает ответ, начинает кидать данные.
Добавлено через 5 минут И я тут подумал, если попыток connect'а много, пока сеть обнаружится, все дела, ведь до подачи питания на плату, сети-то и нет. Так вот, приходит сразу 10 коннектов, у меня не предусмотрена работа с несколькими соединениями. Сервер видит их как много клиентов и открывает столько потоков, сколько пришло connect(). А после и ложится, ибо я работаю только с Connections[0]. Больше не предусмотрел, все равно клиент всегда один. В ThreadBlocking все идет одним потоком и ему до лампочки сколько connect() он получил. Начал, отработал и дисконнектнул клиента.
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
|
10.07.2014, 12:24 | 10 |
Zerorc, ну, какие мысли. Во-первых, "буфер, набиваемый до конца, а после закрывающий соединение" - это уже неправильно. Соединение не следует закрывать, пока программа работает. Общая логика такова: открыли один раз соединение, набиваем буфер, набили отправили, очистили буфер, снова набиваем. И ничего не закрываем, соединение всегда установлено. Практика показывает, что команда на закрытие соединения может придти гораздо быстрее, чем отправляемый буфер данных. И в тот момент, когда сервер начинает что-то пытаться читать из сокета, последний уже закрыт, а то и NULL. Отсюда и ошибка 10053 возникает "удалённый компьютер закрыл подключение".
Во-вторых, совершенно правильная мысль, что неверно обращаться к Connections[0]. Для того, чтобы серверу однозначно правильно что-то читать из сокетов, надо использовать передаваемый в событие OnClientRead параметр Socket, ибо это именно он готов отдать какие-то данные. А самих активных подключений [ServerSocket->ActiveConnections] может быть великое множество.
1
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
|||||||||||||||||||||
10.07.2014, 12:37 [ТС] | 11 | ||||||||||||||||||||
Дело в том что так было в прошлой программе и все работало, теперь я не закрываю соединение, к тому же там буфер был действительно огромный и мог принять большой обьем информации. Знаю, что лучше в файл, потом очищать буфер, дописывать в файлик и тд.
Переделал код таким вот образом
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
||||||
10.07.2014, 12:58 | 12 | |||||
Сообщение было отмечено Zerorc как решение
Решение
Я говорил про это
1
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
|||||||||||
10.07.2014, 13:49 [ТС] | 13 | ||||||||||
Опа! А вот тут я не понял. Я беру получается, обращаясь к определенному соединению, которое, быть может, было когда-то но в данный момент его нет. И из-за этого ошибка 10053.
Но, когда я обращаюсь к активному соединению, посредством
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
|
10.07.2014, 14:36 | 14 |
Connections[] - это все активные соединения сервера. Их может быть несколько, что понятно. На то он и сервер. Допустим их 10. И тут один из клиентов, скажем 5-й, присылает данные. Читать надо данные именно из этого сокета, а не из какого-то определённого. Для этого на него и передаётся в событийную функцию ссылка.
0
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
|
10.07.2014, 14:41 [ТС] | 15 |
Ага, все понятно. Я читал всегда с 0 соединения что в принципе было правильно, ибо клиент один и доколе соблюдение протокола оказывалось филигранным, так сказать, касаемо двух ПК, к примеру.
Но самопальная программа, которая посылает коннект пару сотен раз и может оказаться на любом Connections[?] имела все это ввиду. И если я читаю
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
|
10.07.2014, 15:09 | 16 |
С 0 соединения можно читать, если клиент однозначно один и он регулярно не закрывает подключение. Допустим клиент отправил данные и закрыл подключение, а потом подключился ещё раз, чтобы ещё раз отправить. Так как всё это дело выполняется в некоем потоке, то вполне возможен вариант, что "старый", неиспользуемый уже сокет ещё не удалён из Connections[], ActiveConnections будет равен 2 и очередную порцию данных надо будет читать из Connections[1].
0
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
||||||
10.07.2014, 15:15 [ТС] | 17 | |||||
Тогда правильный ли вариант с отправкой этому клиенту сообщения, если он регулярно может сбросить соединение, к примеру, после снова подключиться. Если я все правильно понял..
0
|
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
|
||||||
10.07.2014, 15:36 | 18 | |||||
Я бы не так сделал. Во-первых, нет никакой гарантии, что активным является именно последний сокет из всех имеющихся. К тому же, придерживаюсь идеологии, что если сервер что-то отправляет, то надо отправлять всем клиентам. Раз все клиенты подключаются к одному серверу, то каждому надо как-то получать результаты работы других. Тот же чат, например. Один сказал, а всем пришло. Во-вторых, совершенно верно, необходимо убедиться, что подключение активно. Поэтому, чтобы убить всех зайцев, я бы посоветовал такую реализацию
1
|
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
|
|
10.07.2014, 15:51 [ТС] | 19 |
Неплохо. Но это тогда выйдет широковещательная посылка. А если, я, к примеру, даю модулю команду отключиться. В принципе, если известен IP, его можно вытащить и по нему выбрать соединение, сравнением, пройтись по всем и отправить нужному.
Но это уже темка для отдельной статьи. С асинхроном разобрался. Спасибо за помощь.
0
|
10.07.2014, 15:51 | |
10.07.2014, 15:51 | |
Помогаю со студенческими работами здесь
19
Socket Error # 10061 Socket error 11001 Socket Error # 10048 Indy 10 (socket error # 10061) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |