I suggest you post the code you currently have for handling one client.
Much easier to discuss change than to create some example that then does not relate to your code at all.
Cheers,
_
I suggest you post the code you currently have for handling one client.
Much easier to discuss change than to create some example that then does not relate to your code at all.
Cheers,
_
Yes Sir,
I am sending my code..both server and client...If Client send text file ,Then code is working fine..but there is problem with pdf file,image file other than text file,..There is problem with the size difference with the file send and receive.my client is Qt-widget and Server is Qt-console.
// myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include "mythread.h"
#define CLIENT_FILE "/home/User1/ClientFile/"
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = 0);
~MyServer();
void startServer();
signals:
public slots:
private:
int server_status;
QTcpServer *tcpServer;
// QTcpSocket *tcpServerConnection;
protected:
void incomingConnection(qintptr socketDescriptor);
};
#endif // MYSERVER_H
// mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
#include <QtNetwork>
#include <QTcpSocket>
#include <QObject>
#include <QByteArray>
#include <QDebug>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <QIODevice>
#include <QDir>
#include <QTextCodec>
#define CLIENT_FILE "/home/User1/ClientFile/"
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(qintptr ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
public slots:
//void readyRead();
void disconnected();
private slots:
void acceptConnection();
void slotReadClient();
private:
QTcpServer *tcpServer;
QTcpSocket *tcpServerConnection;
qintptr socketDescriptor;
QTcpSocket *m_socket;
QString fileName;
QString fileSize;
//QListWidget *showWidget;
//QGridLayout *layout;
bool isInfoGot = false;
int server_status;
qint32 realFileSize;
void sendMessage(int code);
};
#endif // MYTHREAD_H
// myserver.cpp
#include "myserver.h"
#include "mythread.h"
#define CLIENT_PORT 33333
#define SERVER_PORT 44444
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}
MyServer::~MyServer()
{
server_status=0;
}
void MyServer::startServer()
{
if (!this->listen(QHostAddress::Any, SERVER_PORT) && server_status==0)
{
qDebug() << QObject::tr("Unable to start the server: %1.").arg(tcpServer->errorString());
// printf("Server_status is:%d\n",server_status);
}
else
{
server_status=1;
qDebug() << QString::fromUtf8("Server is running");
}
printf("Console start the server\n");
}
void MyServer::incomingConnection(qintptr socketDescriptor)
{
printf("MyServer::incomingConnection\n");
qDebug() << socketDescriptor << " Thread is Connecting...";
QDir::setCurrent(CLIENT_FILE);
MyThread *thread = new MyThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
// mythread.cpp
#include "mythread.h"
#include <QDir>
#define CLIENT_FILE "/home/User1/ClientFile/"
#define CLIENT_PORT 33333
#define SERVER_PORT 44444
MyThread::MyThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
//tcpServerConnection = new QTcpSocket();
}
void MyThread::run()
{
// thread starts here
qDebug() << "MyThread::run()" << " Thread started";
tcpServer = new QTcpServer(this);
tcpServerConnection = new QTcpSocket();
// set the ID
if(!tcpServerConnection->setSocketDescriptor(this->socketDescriptor))
{
// something's wrong, we just emit a signal
emit error(tcpServerConnection->error());
return;
}
// connect socket and signal
// note - Qt:irectConnection is used because it's multithreaded
// This makes the slot to be invoked immediately, when the signal is emitted.
//tcpServer = new QTcpServer(this);
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
if (!tcpServer->listen(QHostAddress::Any, SERVER_PORT) && server_status==0)
// if (!tcpServer->listen(QHostAddress::Any, 44444) && server_status==0)
{
// qDebug() << QObject::tr("Unable to start the server: %1.").arg(tcpServer->errorString());
printf("Server_status is:%d\n",server_status);
}
else
{
server_status=1;
printf("Server_status is:%d\n",server_status);
}
connect(tcpServerConnection, SIGNAL(readyRead()), this, SLOT(slotReadClient()), Qt:irectConnection);
connect(tcpServerConnection, SIGNAL(disconnected()), this, SLOT(disconnected()));
// We'll have multiple clients, we want to know which is which
qDebug() << socketDescriptor << " Client connected";
// make this thread a loop,
// thread will stay alive so that signal/slot to function properly
// not dropped out in the middle when thread dies
exec();
}
void MyThread::acceptConnection()
{
printf("MyThread::acceptConnection()\n");
//Check the connection of Sever
qDebug() << "MainWindow::acceptConnection()";
qDebug() << QString::fromUtf8("Accept the connection");
tcpServerConnection = tcpServer->nextPendingConnection();
connect(tcpServerConnection,SIGNAL(readyRead()),th is, SLOT(slotReadClient()),Qt:irectConnection);
// tcpServer->close();
QDir::setCurrent(CLIENT_FILE);
//QDir::setCurrent(/user)
}
void MyThread::slotReadClient()
{
qDebug() << "MainWindow::slotReadClient()";
QDataStream in(tcpServerConnection);
QByteArray tmpByteArray;
if (!isInfoGot) {
isInfoGot = true;
in >> fileName;
qDebug() << "Received File name:" <<fileName ;
in >> fileSize;
qDebug() <<"Received File size:" << fileSize;
}
/*************/
//check Duplication of files
QString filePath= CLIENT_FILE + fileName;
qDebug () << "file naem is :" << filePath;
if(QFile::exists(filePath))
{
//int qret;
qDebug() << "File is alreday exist,so Overwrite the file";
printf("File is alreday exist,so Overwrite the file\n");
QFile::remove(filePath);
}
/************************/
QFile loadedFile(fileName);
if (loadedFile.open(QIODevice::Append))
{
while (tcpServerConnection->bytesAvailable())
{
qDebug() << "bytesAvailable:" << tcpServerConnection->bytesAvailable();
in >> tmpByteArray;
QString some(tmpByteArray);
if (some=="#END")
{
isInfoGot = false;
QFileInfo fileInfo(loadedFile);
qDebug() << "loaded File size:" << loadedFile.size();
//printf( "loaded File size=%ld \n",loadedFile.size());
if (loadedFile.size() == fileSize.toInt())
{
// QMessageBox::information(this,"Informations","Suce ssfully uploaded to Server");
qDebug() << "Success upload to Server ";
printf( "Success upload to Server \n");
sendMessage(1);
//return 1;
}
else
{
// QMessageBox::warning(this,"Warning","Failed to upload the File to Server");
qDebug() << "Fail upload to Server";
sendMessage(0);
//return 0;
}
break;
}
loadedFile.write(tmpByteArray);
}
loadedFile.close();
}
// get the information
/* QByteArray Data = tcpServerConnection->readAll();
// will write on server side window
qDebug() << socketDescriptor << " Data in: " << Data;
tcpServerConnection->write(Data);*/
}
void MyThread::sendMessage(int code)
{
QTcpSocket *sock = new QTcpSocket(this);
sock->connectToHost("127.0.0.1", CLIENT_PORT);
QDataStream out(sock);
sock->write(QString::number(code).toUtf8().constData()) ;
}
void MyThread::disconnected()
{
qDebug() << socketDescriptor << " Disconnected";
tcpServerConnection->deleteLater();
exit(0);
}
//main.c
#include <QCoreApplication>
#include "myserver.h"
#include "mythread.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
server.startServer();
return a.exec();
}
client code
//client programe
widget.cpp
#include "widget.h"
#include <QDir>
#include <QFileInfo>
#include <QDebug>
#include <QProcess>
#include <QAction>
#include <QIcon>
#include <QFileInfo>
#include <QFileDialog>
#include <QMessageBox>
#include <QAbstractSocket>
#include <QLineEdit>
#define SERVER_FILE "/home/User1/ServerFile/"
#define CLIENT_PORT 33330
#define SERVER_PORT 44440
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
tcpSocket = new QTcpSocket(this);
NameLine= new QLineEdit (this);
NameLine->setPlaceholderText("Enter The User Name");
sendBtn = new QPushButton(this);
sendBtn->setText("Send");
showBtn = new QPushButton(this);
showBtn->setText("Show");
showWidget =new QListWidget(this);
Glayout = new QGridLayout;
// Glayout->addWidget(NameLabel,0,0,1,1);
Glayout->addWidget(NameLine,0,0,1,2);
Glayout->addWidget(showWidget,1,0,1,2);
Glayout->addWidget(showBtn,2,0,1,1);
Glayout->addWidget(sendBtn,2,1,1,1);
setLayout(Glayout);
connect(showBtn, &QPushButton::clicked, this, &Widget::fileShow);
connect(sendBtn, &QPushButton::clicked, this, &Widget:nSend);
}
Widget::~Widget()
{
}
void Widget::fileOpened()
{
qDebug() << " Widget::fileOpened() ";
fileName = QFileDialog::getOpenFileName(this, tr("Open file"));
QFileInfo fileInfo(fileName);
//fileLabel->setText(fileInfo.fileName() + " : " + QString::number(fileInfo.size()));
qDebug() << "Opening The file:" <<fileName;
}
void Widget:nSend()
{
QString UserName;
/**********************************/
if(NameLine->text().isEmpty())
{
QMessageBox::warning(this,"Warning","Please Enter the User Name");
qDebug() << " not User Name ";
}
else
{
QString fileName1;
if(showWidget->selectedItems().count()!=1)
{
QMessageBox::warning(this,"Warning","Please Select a File From List");
return;
}
else
{
//start of Else
QMessageBox::information(this,tr("Information"),tr ("%1 file is selected").arg(showWidget->currentItem()->text()));
//1.Send File first
fileName1= SERVER_FILE + showWidget->currentItem()->text();;
qDebug() << "1.Full File Name:" << fileName ;
//File 1:Transfer User Name as file
QFileInfo fileInfo1(fileName);
// fileLabel->setText(fileInfo.fileName() + " : " + QString::number(fileInfo.size()));
qDebug() << "2.File name with Text Label:" << fileName1;
// tcpSocket->connectToHost("172.16.5.250", CLIENT_PORT);
tcpSocket->connectToHost("127.0.0.1", CLIENT_PORT);
QFile file1(fileName1);
qDebug() << "3.File open is:" << fileName1 ;
QDataStream out1(tcpSocket);
int size1 = 0;
if (file1.open(QIODevice::ReadOnly))
{
QFileInfo fileInfo1(file1);
QString fileName1(fileInfo1.fileName());
out1 << fileName1;
qDebug() << "File name is:" << fileName1;
out1 << NameLine->text();
// qDebug() << "username name is:" << fileName1;
out1 << QString::number(fileInfo1.size());
qDebug() << "File size is:" <<fileInfo1.size();
while (!file1.atEnd())
{
QByteArray rawFile1;
rawFile1 = file1.read(5000);
//false size inc
QFileInfo rawFileInfo1(rawFile1);
size1 += rawFileInfo1.size();
out1 << rawFile1;
qDebug() << "ToSend:"<< rawFile1.size();
}
out1 << "#END";
startServer();
}
} //End of else
} //End of else user name
}
void Widget::startServer()
{
qDebug() << "Widget::startServer().";
qDebug() << "waiting for reply...";
tcpServer = new QTcpServer(this);
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptReplyConnection()));
if (!tcpServer->listen(QHostAddress::Any, SERVER_PORT))
{
//QMessageBox::warning(this,"Warning","Unable to start the server.");
qDebug() << QObject::tr("Unable to start the server: %1.").arg(tcpServer->errorString());
}
else
{
QMessageBox::information(this,"Information","Serve r is connected");
//qDebug() << QString::fromUtf8("Server is connected");
}
}
void Widget::acceptReplyConnection()
{
qDebug() << "Widget::acceptReplyConnection()";
qDebug() << QString::fromUtf8("Waiting for connection");
tcpServerConnection = tcpServer->nextPendingConnection();
connect(tcpServerConnection,SIGNAL(readyRead()),th is, SLOT(slotReadClient()));
tcpServer->close();
}
void Widget::slotReadClient()
{
qDebug() << "Widget::slotReadClient() ";
QDataStream in(tcpServerConnection);
QByteArray tmpArr;
QString tmpString;
in << tmpArr;
qDebug() << "bytesAvailable:" << tcpServerConnection->bytesAvailable();
qDebug() << tmpArr;
if (tmpString.toInt()==1)
{
qDebug() << "successfully uploaded to Server";
}
else
{
qDebug() << "fail to upload to server";
}
}
void Widget::fileShow()
{
qDebug() << " Widget::fileShow() ";
QStringList list_item;
QDir dir(SERVER_FILE);
//Check Whether Name is blank or not
if(NameLine->text().isEmpty())
{
QMessageBox::warning(this,"Warning","Please Enter the User Name");
qDebug() << " not User Name ";
}
else
{
if(!dir.exists())
{
// qDebug() << " not exists ";
QMessageBox::warning(this,"Warning","Cant find the any files of Server path");
// qWarning("canot find the directory");
}
else
{
// qDebug() << " It exists ";
dir.setFilter(QDir::Files | QDir::NoSymLinks );
QFileInfoList list=dir.entryInfoList();
for(int i=0;i<list.size();i++)
{
QFileInfo fileinfo=list.at(i);
list_item << fileinfo.fileName();
}
}
showWidget->clear();
showWidget->addItems(list_item);
} //EnD else for user name
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFileDialog>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
#include <QString>
#include <QLabel>
#include <QNetworkAccessManager>
#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
#include <QProgressBar>
#include <QTcpServer>
#include <QListWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
QFileDialog *fileDialog;
QGridLayout *layout;
QPushButton *fileBtn;
QPushButton *sendBtn;
QPushButton *showBtn;
QLabel *fileLabel;
QLabel *NameLabel;
QLineEdit *NameLine;
QLabel *progressLabel;
QProgressBar *progressBar;
QTcpServer *tcpServer;
QTcpSocket *tcpServerConnection;
QGridLayout *Glayout;
QString fileName;
QTcpSocket *tcpSocket;
QListWidget *showWidget;
void startServer();
~Widget();
public slots:
void fileOpened();
void onSend();
void acceptReplyConnection();
void slotReadClient();
void fileShow();
void displayError(QAbstractSocket::SocketError socketError);
};
#endif // WIDGET_H
//main.c
#include "widget.h"
#include <QApplication>
#include <QLabel>
#include<QPixmap>
#include <QDesktopWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.setFixedWidth(300);
w.setFixedHeight(200);
w.show();
return a.exec();*
}
Ok, this definitely does not need threads on the server side, but that part seems to be reasonably done.
Why is there a QTcpServer member inside the QTcpServer subclass?
Oh my, so many unnecessary includes
Why on earth does the client handler contain a QTcpServer?
That looks reasonably ok.
You are not covering the case that there is not yet enough data for the full string.
The client writes the file name, then a user name, then the file size.
Where are you reading the user name here?
And again, the available data might not be sufficient enough yet.
Well, that will break if you transmit binary data or text data that contains this string.
Totally unnecessary since you know the file size and thus know when you have read all of the file content.
Why don't you simply sent through the connection you already have?
connectToHost() is an asynchronous operation.
You need to connect to the socket's conncted() signal and then continue there.
That is never read on the server side
Why send the number as a string?
You create a QFileInfo object using the 5000 bytes of file1 content as a file name?
Totally unnecessary, the server can simply reply on the already established connection
Why send an empty byte array to the server?
This will always be false because tmpString is empty.
I would suggest the following steps
1) Clean up the code, there are way too many commented out parts, duplicated or unnecessary includes, etc.
2) Ensure that the data serialization and deserialization code matches. Currently the client sends three strings before the file, the server reads only two.
3) In a slot connected to readyRead() you can't assume you are seeing a single write from the client. E.g. the client could write a block with 10 bytes, the server could received this as two blocks. you will need a bit more protocol to handle that.
Cheers,
_
Thanks..i will go through my code once again according to your suggestion.
Bookmarks