Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
 |  |  |  |  |  |
Да, это странный факт. Ну все равно это не меняет главного - send/recv возвращают ошибку. 29.03.02 13:05 Число просмотров: 1069
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
Да, это странный фак[т]. Ну все равно это не меняет главного - send/recv возвращают ошибку.
Я делаю даже сразу после recv/send получение кода ошибки - все равно 183. Т.е. в сокетах ошибка, а через WSAGetLastError не хочет ее получать.
НО!
САМОЕ ГЛАВНОЕ!
Под 9x все отлично работает. А под nt/2000 возникает иногда.....
Вот это пока что для меня загадка. Хотя загадок тут и так хватает.
|
|
<programming>
|
[Win32] [W2k/NT] WinSock: WSAGetLastError()==183 ????????? Подробности внутри. 28.03.02 15:50
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
Hi!
Где-то год назад (примено) я разбирался с этой проблемой, но так и не разобрался.
Получилось толкько "коряво" выкрутиться - поставил тупой цикл, и оно аж c XX-й
попытки "прокатывало". Теперь снова разбираюсь, но тот вариант "меня устал".
Хочу по-уму сделать, а то подвисания страшные начинаются.
Прога - одноконнектный port-mapper.
Вобщем, вот тот текст, который я давно на форумы постил. Никто так и не нашел причину.
Чуть ниже сегодняшние дополнения.
========================
Вот примерный код.
Есть сокет - неблокирующий, привязанный до окна.
По прибытию соотв. мессаги (типа WM_ASYNC_CLIENTEVENT) идет
"case FD_READ:"
и
j=send(currentsock,buf, i, 0);
Если SOCKET_ERROR==j,
достаем код ошибки строкой
Err = WSAGetLastError();
Обычно код ошибки бывает такого типа -
"WSAECONNRESET (10054)" т.е. сам код - 10054
База - 10000, а 54 - конкретная ошибка.
Но у меня (Win2k, NT4) код ошибки возващает такой - 183. И бывает это
не часто. Редко, но метко. И коннекты потом повисают в воздухе.
Т.е. из другой области. Единственный файл, где можно встретить что-то
подходящее, это "error.h" (MVV 6.0) Там такая строка -
"#define ERROR_ALREADY_EXISTS 183"
Что-то я не совсем понимаю происходящего. Что бы это значило ?
От проблемы-то я избавился (но некорректно) - просто в цикле повторяю
send, пока ошибка не пропадет - вроде работает теперь.
===============================================================================
Это было тогда.
А сейчас я сделал буффер для приема в 10 байт и это проблема стала проявляться
как на дрожжах. Тогда я уже понял, что эта ошибка означает что-то вроде перегрузки сети, так как заметил я ее только на NT и 2000, имеющих неск. и-фейсов и работающик
как роутеры. А вот дома под 95 - все отлично.
|
 |
[Win32] [W2k/NT] WinSock: WSAGetLastError()==183 ????????? 29.03.02 16:42
Автор: Cyril <sc> Статус: Member
|
> Вот примерный код. > Есть сокет - неблокирующий, привязанный до окна. > По прибытию соотв. мессаги (типа WM_ASYNC_CLIENTEVENT) идет > "case FD_READ:" > и
Если для получения события ты пользуешься
WSAAsyncSelect попробуй проверить high word of lParam
When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in Winsock2.h.
Note Upon receipt of an event notification message, the WSAGetLastError function cannot be used to check the error value because the error value returned can differ from the value in the high word of lParam.
The error and event codes can be extracted from the lParam using the macros WSAGETSELECTERROR and WSAGETSELECTEVENT, defined in Winsock2.h as:
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)
The use of these macros will maximize the portability of the source code for the application.
> > j=send(currentsock,buf, i, 0); > Если SOCKET_ERROR==j, > достаем код ошибки строкой > Err = WSAGetLastError(); > > Обычно код ошибки бывает такого типа - > > "WSAECONNRESET (10054)" т.е. сам код - 10054 > База - 10000, а 54 - конкретная ошибка. > > Но у меня (Win2k, NT4) код ошибки возващает такой - 183. И > бывает это > не часто. Редко, но метко. И коннекты потом повисают в > воздухе. > Т.е. из другой области. Единственный файл, где можно > встретить что-то > подходящее, это "error.h" (MVV 6.0) Там такая строка - > "#define ERROR_ALREADY_EXISTS 183" > Что-то я не совсем понимаю происходящего. Что бы это > значило ? > От проблемы-то я избавился (но некорректно) - просто в > цикле повторяю > send, пока ошибка не пропадет - вроде работает теперь. > =========================================================== > ==================== > > Это было тогда. > А сейчас я сделал буффер для приема в 10 байт и это > проблема стала проявляться > как на дрожжах. Тогда я уже понял, что эта ошибка означает > что-то вроде перегрузки сети, так как заметил я ее только > на NT и 2000, имеющих неск. и-фейсов и работающик > как роутеры. А вот дома под 95 - все отлично.
|
 |  |
Хорошая мысль. Попробую. Вдруг поможет. 29.03.02 18:33
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
|
|
 |
А можно тебя попросить 28.03.02 18:15
Автор: PS <PS> Статус: Elderman
|
> Err = WSAGetLastError(); Заменить WSAGetLastError(); на GetLastError(); и посмотреть что вернет. А потом поделится с нами :)
Просто интересно....
|
 |  |
OK 28.03.02 18:32
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
|
|
 |  |  |
Посмотрел. GetLastError()==WSAGetLastError()==183 29.03.02 10:40
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
На счет GetLastError() - это вообще возможно потому, что у меня там система записи лога такая - CreateFile с флагами "открыть, а если нету - создать" - там в конец файла каждый раз дописывается что-то.
Может это оттуда та ошибка.
А вот при чем тут WSAGetLastError??
Может обнулить (..SetLastErr..) все до вызова recv(или send)?
|
 |  |  |  |
1 Попробуй обнулить 29.03.02 11:42
Автор: PS <PS> Статус: Elderman Отредактировано 29.03.02 11:45 Количество правок: 1
|
2 Интересно тест проделать (у меня сейчас VC под рукой нет) - поставить ошибку SetLastError, и вызвать WSAGetLastError. Вернет он ее или нет ? Если вернет - то это будет круто.
3 И попробуй посылать своему же сокету, к которому ты доступ имееш ! Тут два варианта есть а. Хоть тебе ошибка и возвращяется но данные приходят на принимающую сторону б. на принимающую ничего не приходит.
> На счет GetLastError() - это вообще возможно потому, что у > меня там система записи лога такая - CreateFile с флагами > "открыть, а если нету - создать" - там в конец файла каждый > раз дописывается что-то. > Может это оттуда та ошибка. > > А вот при чем тут WSAGetLastError?? > Может обнулить (..SetLastErr..) все до вызова recv(или > send)?
|
 |  |  |  |  |
Получай фашист гранату :) 29.03.02 12:40
Автор: PS <PS> Статус: Elderman
|
#include <Windows.h>
#include <stdio.h>
void main()
{
SetLastError( 183 );
int a = WSAGetLastError();
printf( "%ld\n", a );
}
a=183 :)))
|
 |  |  |  |  |  |
Да, это странный факт. Ну все равно это не меняет главного - send/recv возвращают ошибку. 29.03.02 13:05
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
Да, это странный фак[т]. Ну все равно это не меняет главного - send/recv возвращают ошибку.
Я делаю даже сразу после recv/send получение кода ошибки - все равно 183. Т.е. в сокетах ошибка, а через WSAGetLastError не хочет ее получать.
НО!
САМОЕ ГЛАВНОЕ!
Под 9x все отлично работает. А под nt/2000 возникает иногда.....
Вот это пока что для меня загадка. Хотя загадок тут и так хватает.
|
 |  |  |  |  |  |  |
А ты уверен что данные не уходят ? 29.03.02 13:12
Автор: PS <PS> Статус: Elderman
|
Тут возможны варианты:
1. Ошибка ставится раньше и сокет видя ее ничего не отправляет.
2. Ошибка ставится раньше, сокет все отправляет, но возвращяет ошибку.
3. Ошибка возникает в сокете, но между ее возникновением и получением она перебивается 183ей (возможно из другого потока. Что то я не всегда MSDN доверяю...)
Варианты решения : 1. обруби свой логгинг (это - самое главное) 2. Проверь отправляются ли данные вообще при этой ошибке.
|
 |  |  |  |  |  |  |  |
Не проверял 29.03.02 15:51
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
> Тут возможны варианты: > 1. Ошибка ставится раньше и сокет видя ее ничего не > отправляет.
Если мысли почему он так делает? :) Мистика прям какая-то.
> 2. Ошибка ставится раньше, сокет все отправляет, но > возвращяет ошибку.
Аналогично. Просто фантастика.
:)
Думаешь стоит так предполагать? Не могу просто поверить в такой варинт.
> 3. Ошибка возникает в сокете, но между ее возникновением и > получением она перебивается 183ей (возможно из другого > потока. Что то я не всегда MSDN доверяю...)
Поток один. Так что...
> Варианты решения : 1. обруби свой логгинг (это - самое > главное) 2. Проверь отправляются ли данные вообще при этой > ошибке.
Да, это попробую. Буду передавать др. флаги в CreateFile - только чтобы "опен экзист" было.
Посмотрим как оно заговорит. :)
А по поводу второго - что-то лень мне было запускать сниффер и слушать.
Не верится, что если send/recv вернул ошибку, что-то отправилось.
Я вот сейчас взял поновей винсоковые dll (со 2-го с-пака). Попробую еще разок с ними теперь... хотя...
|
 |  |  |  |  |  |  |  |  |
Почему мистика ? 29.03.02 16:24
Автор: PS <PS> Статус: Elderman
|
Например я не знаю внутреннего кода MS и могу только предпологать:
> > Тут возможны варианты: > > 1. Ошибка ставится раньше и сокет видя ее ничего не > > отправляет. > > Если мысли почему он так делает? :) Мистика прям какая-то.
send()
{
if( err != 0 )
return;
.....
}
> > > > 2. Ошибка ставится раньше, сокет все отправляет, но > > возвращяет ошибку. > > Аналогично. Просто фантастика.
Не корректно выразился. Т.е. сокет работает по нормальному, но в конце работы не ставит значение ошибки в "нет ошибки". Вот ты старую и ловиш.
> > > 3. Ошибка возникает в сокете, но между ее > возникновением и > > получением она перебивается 183ей (возможно из другого > > потока. Что то я не всегда MSDN доверяю...) > > Поток один. Так что... Тогда скорей всего это более раняя ошибка. Ты б сбросил бы сам ошибку перед сендом... а ? Самый же простой вариант. Раз бы посмотрели и не гадали бы больше.
|
 |  |  |  |  |  |  |  |  |  |
Поставил WSASetLastError(0) 01.04.02 13:34
Автор: KMiNT21 <http://blog.kmint21.com> Статус: Member
|
Итак, вернулся я к проге.
Поставил WSASetLastError(0) плюс к тому еще в функции, в которой ведется лог изменил атрибуты в CreateFile, чтобы не было "побочных set-ов в LastError".
Все. Ошибка 183 пропала. Как и следовало ожидать.
Это уже победа. Вроде все так просто, но сколько я времени эту ерунду понять не мог. Теперь осталось разобраться дальше что там у меня (если там и так не все в порядке). Мда.. а код я запутал основательно во время отладки. :) Хорошо дома решел все это дело в класс упрятать. Теперь может легче разбираться будет.
Сенкс.
|
|
|