Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для _Lamer
9 / 9 / 1
Регистрация: 16.11.2010
Сообщений: 33

Порт Ввода-вывода, ошибка записи в файл?

15.07.2012, 00:29. Показов 2177. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Суть такова: прога принимает файлы по TCP.
В серверной части испл.порт ввода-вывода (CreateIoCompletionPort, GetQueuedCompletionStatus), организован потоковый пул.
когда сервер обменивается с одним клиентом все работает, клиент передает а сервер принимет 100 файлов подряд и все ОК.
Но когда сервер принимает файлы от двух клиентов одновременно, то происходит следующее:
Сервер актептит клмента, ..... открывает файл
C++
1
2
3
m_hFile = CreateFile((LPCTSTR) pstrFilePath->GetString(), GENERIC_WRITE, NULL, NULL, 
                  CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL);
return (m_hFile != INVALID_HANDLE_VALUE);
связываю описатель файла с портом ввода-вывода
C++
1
fOk = (CreateIoCompletionPort(m_hFile, m_hIOCP, CompKey, dwNumberOfThread) == m_hIOCP);
затем сервер получает содержимое файла (по частям, размер буфера 1024 byte) из сокета (от клиента) и пишет в локальный файл на сервере
C++
1
2
3
4
5
6
7
BOOL fOk = ::WriteFile(m_hFile, (LPCVOID) m_pWbufSend->buf, dwBytesWrite, 
                        NULL, m_pOverlapSend);
if ( fOk == FALSE ) {
    if ( WSA_IO_PENDING != WSAGetLastError() )
        ThrowWSASocketException( WSAGetLastError() );
}
return ( FALSE );
И ТУТ ОШИБКА (try catch перехватывает вызов WriteFile), вставит TRACE-ы в код, вод лог вывода:
....
OpenFile m_hFile=0x1618. FilePath=c:\Out2\tmp\001.Client2_ToServe r.mdb. ThreadId=0x8f8.
CloseFile m_hFile=0x1618, FilePath=c:\Out2\tmp\001.Client2_ToServe r.mdb, ThreadId=0x8f8.
Close Soket pAcceptClient=0x3140000, ThreadId=0x8f8.

Create client pAcceptClient=0x2dd0000, ThreadId=0x8f8.
OpenFile m_hFile=0x1608. FilePath=c:\Out1\tmp\035.Client1_ToServe r.mdb. ThreadId=0x8f8.
CloseFile m_hFile=0x1608, FilePath=c:\Out1\tmp\035.Client1_ToServe r.mdb, ThreadId=0x8f8.
OpenFile m_hFile=0x160c. FilePath=c:\Out1\tmp\007.Client1_ToServe r.mdb. ThreadId=0x8f8.
CloseFile m_hFile=0x160c, FilePath=c:\Out1\tmp\007.Client1_ToServe r.mdb, ThreadId=0x8f8.

Create client pAcceptClient=0x2e40000, ThreadId=0xE18.
OpenFile m_hFile=0x1604. FilePath=c:\Out1\tmp\041.Client1_ToServe r.mdb. ThreadId=0x8f8.

CSocketException::GetErrMess. Error=Неверный дескриптор.
CSocketException::ShowMessageError. Error number=6.
Err. Descrip.="wsasocket.h. Line = 280. ". ThreadId=0x8f8.

Close Soket pAcceptClient=0x2dd0000, ThreadId=0x8f8.
CloseFile m_hFile=0x1604, FilePath=c:\Out1\tmp\041.Client1_ToServe r.mdb, ThreadId=0xE18.
OpenFile m_hFile=0x1604. FilePath=c:\Out2\tmp\003.Client2_ToServe r.mdb. ThreadId=0xE18.
CloseFile m_hFile=0x1604, FilePath=c:\Out2\tmp\003.Client2_ToServe r.mdb, ThreadId=0xE18.
OpenFile m_hFile=0x15f0. FilePath=c:\Out2\tmp\005.Client2_ToServe r.mdb. ThreadId=0xE18.
CloseFile m_hFile=0x15f0, FilePath=c:\Out2\tmp\005.Client2_ToServe r.mdb, ThreadId=0xE18.
....
помогите разобратся почему выскакивает ошибка, когда файл создается, описатель проверяется, ассоциируем с потртом - все ОК, потом пишем данные - ошибка на неправильный описатель (а перед этим заактептился еще один клиент, но до открытия своего файла (003.Client2_ToServer.mdb) еще вроде не дошел), закрываем файл-CloseHandle не ругается.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.07.2012, 00:29
Ответы с готовыми решениями:

Ошибка ввода/вывода 104 - файл не открыт для ввода
var a:array of integer; n,j,i,k: integer; f:text; begin assign(f,'C:\Users\Алла\Desktop\Универ\матрица.txt'); reset(f); ...

Ошибка ввода вывода 103: файл не открыт
Люди добрые выручите,завтра сдавать работу а я обнаружил ошибку при работе одной из процедур.Ошибка ввода/вывода 103: файл не...

Ошибка ввода/вывода 2: Не удается найти указанный файл
program dred9; USES CRT; TYPE rec=record n_rejsa:string; marsh:string; typeplane:string; station:string; price:real;

9
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
15.07.2012, 00:32
WINAPI никогда не использовал.
а так, подобную задачу можно реализовать сильно проще к красивше при использовании boost.asio.
0
 Аватар для _Lamer
9 / 9 / 1
Регистрация: 16.11.2010
Сообщений: 33
15.07.2012, 00:44  [ТС]
Цитата Сообщение от niXman Посмотреть сообщение
WINAPI никогда не использовал.
а так, подобную задачу можно реализовать сильно проще к красивше при использовании boost.asio.
суть в том, что требуется "читаь" и "писать" в дуплексе (одновременно), а значит многопоточная задача.
можно писать на чем угодно, но грабли будут если неправильно организовывать ввод-вывод в многопоточном приложении.
предложение хорошее, да и о библиотеке отзывы неплохие, но проект готов на 99%, и ты предлагаем ВСЕ НАФИГ И ЗАНОВО, да и со средой MinGW я не знаком.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
15.07.2012, 00:48
Цитата Сообщение от _Lamer Посмотреть сообщение
а значит многопоточная задача.
не совсем так...
ибо пока ты не прочтешь, тебе нечего будет писать. а это намекает на однопоточность
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.07.2012, 19:41
затем сервер получает содержимое файла (по частям, размер буфера 1024 byte) из сокета (от клиента) и пишет в локальный файл на сервере
Где год вычитывания ключа из IOCP?

может у тебя оба файла к одному ключу прибиты?
0
 Аватар для _Lamer
9 / 9 / 1
Регистрация: 16.11.2010
Сообщений: 33
16.07.2012, 08:11  [ТС]
вот вызов
C++
1
pListenServer->GetStatus((PULONG_PTR)&pAcceptClient, &dwBytesTransfer/*, dwMilliseconds*/);
, вот реализация
C++
1
2
3
4
5
BOOL GetStatus(PULONG_PTR pCompKey, PDWORD pdwNumBytes, DWORD dwMilliseconds = INFINITE)    {
    LPWSAOVERLAPPED pOverlapped = NULL;
    DWORD dwResult = m_pIocp->GetStatus(pCompKey, pdwNumBytes, &pOverlapped, dwMilliseconds);
    return dwResult;
}
, в ключе передается сам клиент, онже хранит описатель файла, плюс ксасс ioData - который содержит буферы
ввода-выводы, структуры Overlapped, обрабатывает выделение и удаление памяти буферов и структур.
pOverlapped - чистая структура (не производняя с добавлением своих данных, как обычно Рихтер предлагает).

Добавлено через 12 минут
Цитата Сообщение от niXman Посмотреть сообщение
...ибо пока ты не прочтешь, тебе нечего будет писать. а это намекает на однопоточность
если смотреть на одного клиента то так, а я говорю о работе сервера сразу с несколькими клиентами, плюс то что клиент должен "уметь" одновреммено по одному сокету отправлять данные на сервер, а по другому принимать с сервера.
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
16.07.2012, 10:11
подожди. я может что-то забыл из этой всей IOCP, но вот тут:
C++
1
fOk = (CreateIoCompletionPort(m_hFile, m_hIOCP, CompKey, dwNumberOfThread) == m_hIOCP);
Ты кладешь m_hFile с ключом CompKey, а потом как ты получаешь этот хендл из GetQueuedCompletionStatus (ведь это на этот хендл ругается система, что он невалидный?)?
И кто такой у тебя pAcceptClient, который ты вытаскиваешь?
Свой старый код откопал (сервер, который сейчас крутится у брокера и обрабатывает тысячи клиентов одновременно).
Вот место:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void add( const HANDLE new_hdl, ULONG_PTR key ) {
    error_checker chker( WAPIE("IOCP::add") );
    m_handle = chker = CreateIoCompletionPort(new_hdl, m_handle.hdl(), key, 0);
}
 
// success = true
// timeout = false
// error = throw
bool wait( ULONG_PTR & key, DWORD &transferred, DWORD miliseconds) const {
    error_checker chker( WAPIE("IOCP::wait"), WAIT_TIMEOUT );
    LPOVERLAPPED  povl = NULL;
    BOOL res = chker = GetQueuedCompletionStatus(m_handle.hdl(), 
                &transferred, 
                &key, 
                &povl, miliseconds);
    return res ? true : false;
}
первый вызов кладет в очередь с определенным ключом, второй вынимает. потом, по ключу можно получить хендл, который я положил, ну это если у тебя ключ != хендл. если у тебя ошибка невалидный хендл с 2 клиентами, то ты явно что-то не то вынул.
0
 Аватар для _Lamer
9 / 9 / 1
Регистрация: 16.11.2010
Сообщений: 33
16.07.2012, 11:27  [ТС]
для порта ввода-вывода ключ - это указатель на клиента, который подключился к серверу = pAcceptClient.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
/////////////////////////////////////////////////////////////////////////////
// CAcceptClient
class CAcceptClient
{
....
private:
    ...
    IO_OPERATION_DATA* m_pioData;   //  Стуктура OVERLAPPED и буфер (см ниже)
    HANDLE m_hFile;
    ...
public:
    DWORD OpenFile...
    void CloseFile();
когда сервер актептит клиента
C++
1
2
3
4
PCAcceptClient pAcceptClient=(PCAcceptClient) VirtualAlloc(NULL, sizeof(CAcceptClient),...
...
// Ассоциируем  сокет клиента с портом завершения
m_pIocp->AssociateSocket( pAcceptClient->GetSocket(), (ULONG_PTR) pAcceptClient );
вот раелизация m_pIocp
C++
1
2
3
4
5
6
7
8
9
BOOL AssociateDevice(HANDLE hDevice, ULONG_PTR CompKey) {
  BOOL fOk=(CreateIoCompletionPort(hDevice, m_hIOCP, CompKey, dwNumberOfThread)==m_hIOCP);
  ASSERT(fOk);
  return(fOk);
}
 
BOOL AssociateSocket(SOCKET hSocket, ULONG_PTR CompKey) {
    return(AssociateDevice((HANDLE) hSocket, CompKey));
}
получается когда вызываем GetQueuedCompletionStatus (GetStatus)
C++
1
2
3
4
5
6
7
8
9
10
// Ожидаем завершения операции ввода/вывода  на любом сокете, связанным с данным портом
dwBytesTransfer= 0;
if ( dwResult=pListenServer->GetStatus( (PULONG_PTR)&pAcceptClient, &dwBytesTransfer ) ){
    if ( dwResult == (DWORD)-1 )
        ThrowWSASocketException;//  socket закрыт ПРОВЕРЕНО
    else
        dwBytesTransfer = 0;
    }
 
    ASSERT_POINTER(pAcceptClient, CAcceptClient);
GetQueuedCompletionStatus в переменной PULONG_PTR lpCompletionKey вернет указатель на pAcceptClient, а в каждом экземпляре pAcceptClient-а свои данные: m_hFile, m_pioData (в нем
C++
1
2
3
4
5
6
7
class IO_OPERATION_DATA /*: public OVERLAPPED*/
{
...
private:
    u_long          m_ulBuffBytes;
    LPWSAOVERLAPPED m_pOver;
    LPWSABUF        m_pwbuf;
) в pAcceprCliet определено IO_OPERATION_DATA* m_pioData; (см.выше)

Добавлено через 19 минут
villu,
вопрос, если у тебя абсолютно рабочий вариант с портом. расскажи пару моментов
1.что ты используешь в качестве ключа
2.ты испотльзуешь "читсую" сткуктуру OVERLAPPED или производный класс от OVERLAPPED (его обычно дополняют буфером...)
3.твой клиент использует одну структуру OVERLAPPED для записи и чтения в сокет или для записи своя а для чтения своя?
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
16.07.2012, 11:36
кажется понял. смотри код.
C++
1
2
3
4
5
wapi_file_handle f(L"C:\\tmp.txt");
    f.create();
    OVERLAPPED ovl;
    DWORD w;
    BOOL res = WriteFile(f.hdl(), "111", 3, &w, &ovl);// тут получим 6, хотя хендл живой
а тут:
C++
1
2
3
4
5
wapi_file_handle f(L"C:\\tmp.txt");
    f.create();
    OVERLAPPED ovl = {0}; // !!
    DWORD w;
    BOOL res = WriteFile(f.hdl(), "111", 3, &w, &ovl); // тут все ok, получаем или err=0 или err=997
Похоже, у тебя поле event в структуре не нулевое и вызов считает, что этот евент нужно дернуть

Добавлено через 5 минут
Цитата Сообщение от _Lamer Посмотреть сообщение
villu,
вопрос, если у тебя абсолютно рабочий вариант с портом. расскажи пару моментов
1.что ты используешь в качестве ключа
2.ты испотльзуешь "читсую" сткуктуру OVERLAPPED или производный класс от OVERLAPPED (его обычно дополняют буфером...)
3.твой клиент использует одну структуру OVERLAPPED для записи и чтения в сокет или для записи своя а для чтения своя?
1: в качестве ключа у меня так же указатель на объект клиента
2: производный, который, кстати в конструкторе забивается нулями ()
3: зависит от клиента. Есть клиенты, где у меня работа идет вопрос-ответ, тогда только одна, есть те, которые могут читать и писать "рандомно", в зависимости от внешних факторов. Там на сторону чтения свой, на запись свой.
1
 Аватар для _Lamer
9 / 9 / 1
Регистрация: 16.11.2010
Сообщений: 33
16.07.2012, 14:57  [ТС]
Цитата Сообщение от villu Посмотреть сообщение
OVERLAPPED ovl = {0}; // !!
а это вариант, я при вызове WSARecv данные обнулял а при записе в файл забыл.
ща запущу на тестирование, по результу отпишусь.

Добавлено через 3 часа 12 минут
villu, походу ОНО, обнулил эвент и все закрутилось, спасиб.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.07.2012, 14:57
Помогаю со студенческими работами здесь

Ошибка ввода/вывода 2: не удается найти указанный файл
Написал программу, файлы input.txt и output.txt создал(хранятся в одной папке с программой), Pascal ABC от администратора запустил, но...

Ошибка ввода/вывода 2: Не удается найти указанный файл
Program baza; Uses CRT; label rew; type spisok=record fam:string; imya:string; otch:string; adres:string; ...

Ссылка на порт ввода/вывода
typedef struct { volatile unsigned char *port_l; unsigned char pin_l; volatile unsigned char *port_r; unsigned...

Ошибка при работе с потоками ввода (вывода) в файл (из файла)
Изучаю перегрузку операторов ввода/вывода с файлом и без. Вылетает такая ошибка при отработанном коде: Необработанное исключение по...

Порт завершения ввода и вывода данных
Что из себя представляет порт завершения вывода данных? На некоторых сайтах пишут что это очередь overlapped дескрипторов,это правильное...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД 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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru