Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/48: Рейтинг темы: голосов - 48, средняя оценка - 4.73
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46

Server Socket, Asynchronous socket error 10053

08.07.2014, 11:50. Показов 9995. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Сразу к делу. Работаю с компонентом ServerSocket, при приеме данных возникает asynchronous socket error 10053.
Сервер работает в режиме stNonBlocking, клиент - постоянно посылает какую-то информацию. Задача - принять и обработать. Интервал между посылками, примерно 20ms а размер пакета 150 байт.

C++
1
2
std::vector <unsigned char> dataAll; //приемный контейнер
BYTE buf[2000];                 //переменный буфер
C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
        length = ServerSocket1->Socket->Connections[0]->ReceiveLength();
        ServerSocket1->Socket->Connections[0]->ReceiveBuf(buf, length);
        dataAll.resize(dataAll.size() + length);
        memcpy(&dataAll[dataAll.size() - length], &buf, length);
        lengthAll+=length; Form1->Edit2->Text = lengthAll;
Принимаю в контейнер, таким вот способом, по событию чтения клиента. Так вот, открываю порт, слушаю, жду connect'a, пока все в порядке. Но как только клиент подключается, он сразу же начинает забрасывать потоком данных и не успев принять, возникает error 10053.
Какие есть варианты? Быть может прописать что-то в OnClientError, помимо ErrorCode = 0.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.07.2014, 11:50
Ответы с готовыми решениями:

Asynchronous socket error 10060
Добрый день. Я делаю программу с использованием Socket. Вот код сервера. ...

Ошибка: Asynchronous socket error 10061
Делаю клиент и сервер с помощью компонентов TClientSocket и TServerSocket. На одной машине все работает. Пытаюсь запустить с виртуальной -...

Server(Client)Socket
Всем привет. Собираюсь сделать передачу команд между сервером-клиентом через socket'ы, но возник один вопрос: будут ли проблемы с...

18
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,140
Записей в блоге: 3
08.07.2014, 14:29
Скорее всего не хватает выделенной памяти на прием в Вашем "контейнере"
0
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
08.07.2014, 17:41  [ТС]
Так Вектор в том-то и дело что сам наращивается и ему все равно какой длинны он будет, пока не займет в теории всю оперативную память компьютера.
Другое дело что массив в векторе в памяти идет как бы подряд и если какой-то участок памяти на его доблестном разрастании занят, то он переносит весь вектор в новый участок плюс резервирует место, при каждом наращивании все больше и больше.
Проблема в том что как только клиент присоединяется, моментально вылетает ошибка или вовсе программа убивается виндой. Не понимаю почему так.

Добавлено через 2 часа 21 минуту
Попробовал стандартный чатик из Examples в builder. Все великолепно принимает, простой как палка.

C++
1
2
3
4
5
void __fastcall TChatForm::ServerSocketClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
  Memo2->Lines->Add(Socket->ReceiveText());  
}
Опять же проблема значится в алгоритме записи моем. У кого есть какие идеи как записать, если не с помощью вектора. В принципе, мне ведь все равно, идут данные подряд в памяти или нет. Можно использовать и контейнеры с указателем на следующую ячейку. Может повозиться с динамическим буфером, второй побольше создать, туда перенести, как заполнен первый а потом удалить его. Есть-какие предложения?
Или использовать ReceiveText, загонять в string, а после уже разбивать как захочу?
Но разве это из-за ReceiveBuf() запара? Или все-таки с вектором перемудрил?
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,140
Записей в блоге: 3
08.07.2014, 18:13
можно попробовать так

C
1
2
3
int len = ServerSocket1->Socket->ReceiveLength();
char* buf= new char[len+1];
ServerSocket1->Socket->ReceiveBuf((void*)buf, len);
1
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
09.07.2014, 10:21
Dinkin, прежде, чем ковыряться в коде, имеет смысл ознакомиться с самой ошибкой. 10053 означает "удалённый компьютер закрыл подключение". Из-за чего-то. Т.е., при попытке доступа к сокету, соединение уже разорвано. Думаю, надо смотреть клиента...
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,140
Записей в блоге: 3
09.07.2014, 11:46
Цитата Сообщение от c0rvax Посмотреть сообщение
смысл ознакомиться с самой ошибкой. 10053 оз
Так он же пишет, что при нормальной отправке данных все норм...а данная ошибка в основном распространяется на сервер, который закрывает соединение, если что-то не успел/не смог обработать по какой-либо причине.
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
09.07.2014, 12:03
Dinkin, можешь, конечно, остаться при своих. А можешь показать код, как происходит отправка. Или хотя бы сделай предварительную проверку, активно ли подключение
C++
1
2
3
4
if( ServerSocket1->Socket->Connections[0]->Connected )
{
  ...
}
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,140
Записей в блоге: 3
09.07.2014, 13:05
так я то че, не мне же помогать,с меня за чем код?) а парень свой код выше показал, при каких случаях у него ошибка
0
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 11:03  [ТС]
Клиент, это плата, подсоединенная к чипу Withnet Ethernet W5100, она просто кидает connect и если сервер отвечает, начинает забрасывать данные. Дело в том что другая прога, которую я писал на Delphi, работает, хотя в builder'e сделал все аналогично, за исключением вектора. Там был статический буфер, набиваемый до конца, а после закрывающий соединение. И еще, как я понял Indy server работает в Thread blocking а Server socket в nonBlocking.
Теперь же задача стоит в том, что мы не знаем сколько будет данных, поэтому и вектор. Плата шлет огромное количество попыток connect() и как только получает ответ, начинает кидать данные.

C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
        mLog->SelAttributes->Color = clBlue;
        mLog->Lines->Add("[" + TimeToStr(Time()) + "] подключен: " + ServerSocket1->Socket->Connections[0]->RemoteAddress);
        Edit1->Text = Form1->ServerSocket1->Socket->Connections[0]->RemoteAddress;
 
}
Особенность только в работе с платой, но дело ведь в том что на другой проге все ок, а с этими сокетами ошибки лезут вот такие.

Добавлено через 5 минут
И я тут подумал, если попыток connect'а много, пока сеть обнаружится, все дела, ведь до подачи питания на плату, сети-то и нет. Так вот, приходит сразу 10 коннектов, у меня не предусмотрена работа с несколькими соединениями. Сервер видит их как много клиентов и открывает столько потоков, сколько пришло connect(). А после и ложится, ибо я работаю только с Connections[0]. Больше не предусмотрел, все равно клиент всегда один.
В ThreadBlocking все идет одним потоком и ему до лампочки сколько connect() он получил. Начал, отработал и дисконнектнул клиента.
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
10.07.2014, 12:24
Zerorc, ну, какие мысли. Во-первых, "буфер, набиваемый до конца, а после закрывающий соединение" - это уже неправильно. Соединение не следует закрывать, пока программа работает. Общая логика такова: открыли один раз соединение, набиваем буфер, набили отправили, очистили буфер, снова набиваем. И ничего не закрываем, соединение всегда установлено. Практика показывает, что команда на закрытие соединения может придти гораздо быстрее, чем отправляемый буфер данных. И в тот момент, когда сервер начинает что-то пытаться читать из сокета, последний уже закрыт, а то и NULL. Отсюда и ошибка 10053 возникает "удалённый компьютер закрыл подключение".

Во-вторых, совершенно правильная мысль, что неверно обращаться к Connections[0]. Для того, чтобы серверу однозначно правильно что-то читать из сокетов, надо использовать передаваемый в событие OnClientRead параметр Socket, ибо это именно он готов отдать какие-то данные. А самих активных подключений [ServerSocket->ActiveConnections] может быть великое множество.
1
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 12:37  [ТС]
Дело в том что так было в прошлой программе и все работало, теперь я не закрываю соединение, к тому же там буфер был действительно огромный и мог принять большой обьем информации. Знаю, что лучше в файл, потом очищать буфер, дописывать в файлик и тд.

Переделал код таким вот образом
C++
1
 int concnt = -1; //счетчик действующих клиентов. Глобально
C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
         concnt++;
        mLog->SelAttributes->Color = clBlue;
        mLog->Lines->Add("[" + TimeToStr(Time()) + "] подключен: " + ServerSocket1->Socket->Connections[concnt]->RemoteAddress);
        Edit1->Text = Form1->ServerSocket1->Socket->Connections[concnt]->RemoteAddress;
}
C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
        mLog->SelAttributes->Color = clGray;
        mLog->Lines->Add("[" + TimeToStr(Time()) + "] отключен: " + ServerSocket1->Socket->Connections[concnt]->RemoteAddress);
        GraphTimer->Enabled = false;
        concnt--;
}
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
        unsigned len = ServerSocket1->Socket->Connections[concnt]->ReceiveLength();
        BYTE* buf= new BYTE[len+1];
        ServerSocket1->Socket->Connections[concnt]->ReceiveBuf((char*)buf, len);
dataAll.resize(dataAll.size() + len);
        memcpy(&dataAll[dataAll.size() - len], buf, len);
        lenAll+=len; Form1->Edit2->Text = lenAll;
 
        delete buf;
что происходит. Пишет что клиент подключен, может и раз десять так написать, подряд и принимает какими-то промежутками данные. Все равно не то что нужно. Соединение не закрываю вообще.
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
10.07.2014, 12:58
Лучший ответ Сообщение было отмечено Zerorc как решение

Решение

Я говорил про это
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
        unsigned len = Socket->ReceiveLength(); // сокет, который из параметров !!!
        BYTE* buf= new BYTE[len+1];
        Socket->ReceiveBuf((char*)buf, len);
dataAll.resize(dataAll.size() + len);
        memcpy(&dataAll[dataAll.size() - len], buf, len);
        lenAll+=len; Form1->Edit2->Text = lenAll;
 
        delete buf;
1
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 13:49  [ТС]
Опа! А вот тут я не понял. Я беру получается, обращаясь к определенному соединению, которое, быть может, было когда-то но в данный момент его нет. И из-за этого ошибка 10053.

Но, когда я обращаюсь к активному соединению, посредством
C++
1
unsigned len = Socket->ReceiveLength(); // сокет, который из параметров !!!
то данные я гарантированно получу. Так?

C++
1
2
3
4
5
6
7
8
        unsigned len = Socket->ReceiveLength();
        BYTE* buf= new BYTE[len+1];
        Socket->ReceiveBuf((char*)buf, len);
        dataAll.resize(dataAll.size() + len);
        memcpy(&dataAll[dataAll.size() - len], buf, len);
        lenAll+=len; Form1->Edit2->Text = lenAll;
 
        delete buf;
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
10.07.2014, 14:36
Connections[] - это все активные соединения сервера. Их может быть несколько, что понятно. На то он и сервер. Допустим их 10. И тут один из клиентов, скажем 5-й, присылает данные. Читать надо данные именно из этого сокета, а не из какого-то определённого. Для этого на него и передаётся в событийную функцию ссылка.
0
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 14:41  [ТС]
Ага, все понятно. Я читал всегда с 0 соединения что в принципе было правильно, ибо клиент один и доколе соблюдение протокола оказывалось филигранным, так сказать, касаемо двух ПК, к примеру.
Но самопальная программа, которая посылает коннект пару сотен раз и может оказаться на любом Connections[?] имела все это ввиду.
И если я читаю
данные именно из этого сокета, а не из какого-то определённого
, то все в порядке)
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
10.07.2014, 15:09
С 0 соединения можно читать, если клиент однозначно один и он регулярно не закрывает подключение. Допустим клиент отправил данные и закрыл подключение, а потом подключился ещё раз, чтобы ещё раз отправить. Так как всё это дело выполняется в некоем потоке, то вполне возможен вариант, что "старый", неиспользуемый уже сокет ещё не удалён из Connections[], ActiveConnections будет равен 2 и очередную порцию данных надо будет читать из Connections[1].
0
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 15:15  [ТС]
Тогда правильный ли вариант с отправкой этому клиенту сообщения, если он регулярно может сбросить соединение, к примеру, после снова подключиться. Если я все правильно понял..

C++
1
2
3
4
5
void __fastcall TForm1::Button3Click(TObject *Sender)
{
... //проверки есть ли соединение, во избежание вылетов
Form1->ServerSocket1->Socket->Connections[ServerSocket1->Socket->ActiveConnections-1]->SendBuf(buff,100);
}
Я не могу считать событие ибо событие у меня здесь - это нажатие кнопочки. Единственный выход?
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
10.07.2014, 15:36
Я бы не так сделал. Во-первых, нет никакой гарантии, что активным является именно последний сокет из всех имеющихся. К тому же, придерживаюсь идеологии, что если сервер что-то отправляет, то надо отправлять всем клиентам. Раз все клиенты подключаются к одному серверу, то каждому надо как-то получать результаты работы других. Тот же чат, например. Один сказал, а всем пришло. Во-вторых, совершенно верно, необходимо убедиться, что подключение активно. Поэтому, чтобы убить всех зайцев, я бы посоветовал такую реализацию
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  for( int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++ )
  {
    TCustomWinSocket* ASocket = ServerSocket1->Socket->Connections[ i ];
    if( ASocket && ASocket->Connected )
    {
      ASocket->SendBuf( buff, 100 );
    }
  }
}
1
1 / 1 / 1
Регистрация: 14.03.2014
Сообщений: 46
10.07.2014, 15:51  [ТС]
Неплохо. Но это тогда выйдет широковещательная посылка. А если, я, к примеру, даю модулю команду отключиться. В принципе, если известен IP, его можно вытащить и по нему выбрать соединение, сравнением, пройтись по всем и отправить нужному.
Но это уже темка для отдельной статьи. С асинхроном разобрался. Спасибо за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.07.2014, 15:51
Помогаю со студенческими работами здесь

Client и Server Socket
Доброго дня суток , подскажите как можно переслать , к примеру , с клиента на сервер 2 переменные , я знаю только как можно одну: void...

Socket Error # 10061
привет всем. У меня проблема. Добавил IdFTP. Написал в билдере: void __fastcall TForm1::Button1Click(TObject *Sender) { ...

Socket error 11001
Вот если нету соединения с нетом, то вылетает ошибка socked error 11001. Можно ли как-нибудь её автоматически закрывать, чтобы при этом...

Socket Error # 10048
Добрый день. У меня при использовании компонентов TMNFTP, TIdFTP, TIdHTTPServer при ввода команды Имя компонента-&gt;Active = true; ...

Indy 10 (socket error # 10061)
Доброго! Ни как не могу отловить ошибку отсутствия сервера, что бы просто говорила, что его нет.


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru