Russian Qt Forum
Ноябрь 23, 2024, 11:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Передача файлов по сети  (Прочитано 28011 раз)
winneru
Гость
« Ответ #15 : Октябрь 12, 2009, 13:38 »

Ты меня просто спас.То есть это уже готовые коды и для клиента и для сервера?
Записан
TukiNov
Гость
« Ответ #16 : Октябрь 12, 2009, 13:47 »

2 TukiNov
Несколько вопросов/комментариев.  Улыбающийся
* Почему malloc, а не new?
* Для чего нужен QDataStream? У QFile есть свой метод read, который читает нужное количество байт и возвращает готовый QByteArray (malloc/free не понадобятся).
* У QTcpSocket есть метод write, который в качестве параметра получает QByteArray.
Ну теоретически моно уйти от char, malloc, free Улыбающийся Но прога в первую очередь заточена под МСВС Улыбающийся а там граблей с Qt4 хватает Улыбающийся Да и мне проще так регулировать размер пакета. А так все комменты по делу Улыбающийся
Записан
TukiNov
Гость
« Ответ #17 : Октябрь 12, 2009, 13:47 »

Ты меня просто спас.То есть это уже готовые коды и для клиента и для сервера?
ну да. Только это просто обработка входящий данных и отправка Улыбающийся сам сервер - клиент тебе писать Улыбающийся
Записан
TukiNov
Гость
« Ответ #18 : Октябрь 12, 2009, 13:50 »

2 TukiNov
Несколько вопросов/комментариев.  Улыбающийся
* Для чего нужен QDataStream? У QFile есть свой метод read, который читает нужное количество байт и возвращает готовый QByteArray (malloc/free не понадобятся).
qint64 QIODevice::read ( char * data, qint64 maxSize )
QByteArray QIODevice::read ( qint64 maxSize )
Первая все равно в char* кидает, вторая не подходит
Записан
BRE
Гость
« Ответ #19 : Октябрь 12, 2009, 15:26 »

qint64 QIODevice::read ( char * data, qint64 maxSize )
QByteArray QIODevice::read ( qint64 maxSize )
Первая все равно в char* кидает, вторая не подходит
Почему не подходит?
Записан
TukiNov
Гость
« Ответ #20 : Октябрь 12, 2009, 22:00 »

qint64 QIODevice::read ( char * data, qint64 maxSize )
QByteArray QIODevice::read ( qint64 maxSize )
Первая все равно в char* кидает, вторая не подходит
Почему не подходит?
а как с помощью её прочитать от фрагмент ?(не с начала файла а например с середины)
Записан
BRE
Гость
« Ответ #21 : Октябрь 12, 2009, 22:01 »

а как с помощью её прочитать от фрагмент ?(не с начала файла а например с середины)
Не понял?  Шокированный
Точно также как и с помощью qint64 QIODevice::read ( char * data, qint64 maxSize ).


Записан
BRE
Гость
« Ответ #22 : Октябрь 12, 2009, 22:21 »

Еще несколько моментов.
Код
C++ (Qt)
   file.open(QFile::ReadOnly);
   QDataStream read(&file);
   lBytes = 0;
   char * ch;
   ch = (char*)malloc(sizeof(char) * 1024);
   ch[1023] = '\0';
   while(!read.atEnd()){
     int l = read.readRawData(ch, sizeof(char)*1023);
     QByteArray ba(ch, sizeof(char)*l);
 
     lBytes += m_pTcpSocket->write(ba, sizeof(char)*l);
     m_pTcpSocket->flush();
// !!! проверка будет работать корректно только при первой операции записи в сокет (т.к. lBytes += ...)
     if (-1 == lBytes){
       qWarning() << "Error";
       m_pTcpSocket->close();
// !!! при ошибке будет "течь" память (буфер ch не освобождается)
       return;
     }
     float procentage = ((float)lBytes / package.filelength) * 100;
     emit setProcentage((int)procentage);
   }//while(!readEnd())
   free((void*)ch);
 
Записан
TukiNov
Гость
« Ответ #23 : Октябрь 13, 2009, 09:00 »

Еще несколько моментов.
Код
C++ (Qt)
   file.open(QFile::ReadOnly);
   QDataStream read(&file);
   lBytes = 0;
   char * ch;
   ch = (char*)malloc(sizeof(char) * 1024);
   ch[1023] = '\0';
   while(!read.atEnd()){
     int l = read.readRawData(ch, sizeof(char)*1023);
     QByteArray ba(ch, sizeof(char)*l);
 
     lBytes += m_pTcpSocket->write(ba, sizeof(char)*l);
     m_pTcpSocket->flush();
// !!! проверка будет работать корректно только при первой операции записи в сокет (т.к. lBytes += ...)
     if (-1 == lBytes){
       qWarning() << "Error";
       m_pTcpSocket->close();
// !!! при ошибке будет "течь" память (буфер ch не освобождается)
       return;
     }
     float procentage = ((float)lBytes / package.filelength) * 100;
     emit setProcentage((int)procentage);
   }//while(!readEnd())
   free((void*)ch);
 

Спасиб Улыбающийся с этим согласен Улыбающийся упустил Улыбающийся было lBytes =, но решил переменную использовать в подсчете процентов Улыбающийся исправлю Улыбающийся
Записан
BRE
Гость
« Ответ #24 : Октябрь 13, 2009, 09:04 »

Спасиб Улыбающийся с этим согласен Улыбающийся упустил Улыбающийся было lBytes =, но решил переменную использовать в подсчете процентов Улыбающийся исправлю Улыбающийся
Попробуй сделать чтение/запись на функциях работающих с QByteArray. Думаю код упроститься, по крайней мере буфер уйдет.
P.S. В подобных случаях, буфер ch лучше выделять на стеке, тогда и проблем с освобождением не будет.
Записан
TukiNov
Гость
« Ответ #25 : Октябрь 13, 2009, 12:31 »

Спасиб Улыбающийся с этим согласен Улыбающийся упустил Улыбающийся было lBytes =, но решил переменную использовать в подсчете процентов Улыбающийся исправлю Улыбающийся
Попробуй сделать чтение/запись на функциях работающих с QByteArray. Думаю код упроститься, по крайней мере буфер уйдет.
P.S. В подобных случаях, буфер ch лучше выделять на стеке, тогда и проблем с освобождением не будет.

Оке, попробую.
Слух, у мя тут вопрос созрел.
У меня клиент, начинает передавать файл как только установили соединение, то есть в connectedServer()
Код:
m_pTcpSocket = new QTcpSocket();
  connect(m_pTcpSocket, SIGNAL(connected()), SLOT(connectedServer()));
а сервер обрабатывает входящие соединения в
Код:
void ThreadServer::run()
{
  m_pTcpSocket = new QTcpSocket();
  if(!m_pTcpSocket->setSocketDescriptor(socketDescriptor)){
    qDebug() << m_pTcpSocket->errorString();
    return;
  }
...
...
...
чё то мне кажется я не правильно сделал Улыбающийся
« Последнее редактирование: Октябрь 13, 2009, 12:35 от TukiNov » Записан
BRE
Гость
« Ответ #26 : Октябрь 13, 2009, 14:10 »

Клиент
Можно это делать и синхронно:
Код
C++ (Qt)
socket->connectToHost( ... );
if( !socket->waitForConnected( timeout ) )
{
// ОШИБКА: Соединение не произошло
}
 
// Начали передачу данных
 

Сервер
Я правильно понял, что ты в обработчике сигнала newConnection, запускаешь поток, который будет обслуживать данное подключение?
Если да, то можно использовать сам объект QTcpSocket, который возвращает nextPendingConnection ():
Код
C++ (Qt)
void Server::slot_newConnection()
{
QTcpSocket *client = nextPendingConnection();
if( !client )
return;
 
Thread *t = new Thread( client );
t->start();
}
 
Thread::Thread( QTcpSocket *socket )
{
Q_ASSERT( m_client );
m_client = socket;
m_client->moveToThread( this );
}
 
void Thread::run()
{
// работает с сокетом клиента m_client
}
 
И не забываем убивать объект m_socket при disconnect.
« Последнее редактирование: Октябрь 13, 2009, 14:23 от BRE » Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.318 секунд. Запросов: 20.