-
Notifications
You must be signed in to change notification settings - Fork 0
/
mytcp.cpp
178 lines (177 loc) · 5.9 KB
/
mytcp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "mytcp.h"
myTcp::myTcp(QObject *parent):
QObject(parent)
{
tcpServer = new QTcpServer(this);
peerList = QMap<QString, QTcpSocket*>();
outBuf.resize(0);
sumPeer = 0;
serverPort = 6666;
totalSize = 0;
sizeToWrite = 0;
sizeWritten = 0;
isSendFile = false;
loadSize = 64*1024; //每次文件传输的包大小上限64KB
//loadSize = 1024*1024; //每次文件传输的包大小上限1024KB
file = NULL;
cryptoFile = NULL;
if(!tcpServer->listen(QHostAddress::Any, serverPort))
{
qDebug() <<"service start listener failed!";
tcpServer->close();
} else {
qDebug() << "service startup listener succeed!";
conn = connDB::getDB();
}
connect(tcpServer, &QTcpServer::newConnection, this, &myTcp::onNewConnection);
}
myTcp::~myTcp()
{
if(!tcpServer)
delete tcpServer;
}
void myTcp::onNewConnection()
{
QTcpSocket *newClient = tcpServer->nextPendingConnection();
newClient->setSocketOption(QAbstractSocket::LowDelayOption, 1);
if(NULL == newClient)
{
qDebug() <<"socket is error!";
return;
}
sumPeer += 1;
QString clientIp = newClient->peerAddress().toString();
peerList.insert(clientIp, newClient);
connect(newClient, SIGNAL(readyRead()), this, SLOT(slot_readData()));
connect(newClient, SIGNAL(disconnected()), this, SLOT(onDisConnection()));
connect(newClient, SIGNAL(bytesWritten(qint64)), this, SLOT(slotSendFile(qint64)));
updatePeerList();
}
void myTcp::onDisConnection()
{
sumPeer -= 1;
QTcpSocket *disClient = static_cast<QTcpSocket *>(this->sender());
QString disClientIp = disClient->peerAddress().toString();
peerList.remove(disClientIp);
disClient->close();
}
void myTcp::updatePeerList()
{
QMap<QString, QTcpSocket*>::Iterator iter;
for(iter = peerList.begin(); iter != peerList.end(); )
{
QAbstractSocket::SocketState curState = (*iter)->state();
if(QAbstractSocket::UnconnectedState == curState ||
QAbstractSocket::ClosingState == curState)
{
qDebug() << "erase closed socket user : " << iter.key();
iter = peerList.erase(iter);
} else
++iter;
}
}
void myTcp::slot_readData()
{
QTcpSocket *makerSocket = static_cast<QTcpSocket *>(this->sender());
QByteArray byteData;
while(makerSocket->bytesAvailable() > 0)
{
byteData = makerSocket->readAll();
}
QString clientIp = makerSocket->peerAddress().toString();
QString info = static_cast<QString>(byteData);
QString result;
qDebug() << "service recieve user: " << clientIp << " sended text";
QStringList list = info.split(' ');
if(list.at(0) == "register") {
result = conn->userRegister(info);
sendDate(makerSocket, result);
qDebug()<< clientIp<<"register succeed.";
}
else if(list.at(0) == "login") {
result = conn->userLogin(info);
sendDate(makerSocket, result);
if(result == "true")
qDebug()<< clientIp<<"login succeed.";
else
qDebug()<< clientIp<<"register failed.";
}
else if(list.at(0) == "booklist")
{
result = conn->userList(list.at(1));
sendDate(makerSocket, result.toUtf8());
}
else if(list.at(0) == "read")
{
result = conn->userRead(info);
file = new QFile(result);
//通过计算用户密码的Hash值来获得AES秘钥
QString pwd = (info.split('#')).at(2);
qDebug() << "pwd:" << pwd;
QByteArray key;
QByteArray p;
key = QCryptographicHash::hash(p.append(pwd), QCryptographicHash::Md5);
unsigned char *aesKey = (unsigned char *)key.data();
//使用AES算法加密读者希望阅读的图书
AES aes(Bits128, aesKey);
QString curFileName = result.right(result.size() - result.lastIndexOf('\\') - 1);
QString cryptoFileName = result.left(result.lastIndexOf("\\") + 1);
QDir *workdir = new QDir(cryptoFileName + "EncryptedBooks");
if(!workdir->exists()) //创建用于加密图书的工作目录
workdir->mkdir(cryptoFileName + "EncryptedBooks");
cryptoFileName = cryptoFileName + "EncryptedBooks\\" + curFileName;
cryptoFile = new QFile(cryptoFileName);
if(cryptoFile->exists())
cryptoFile->remove();
//开始AES文件加密
aes.FileCipher(file, cryptoFile);
//开始传输文件描述信息
if(cryptoFile->open(QFile::ReadOnly))
{
isSendFile = true;
totalSize = cryptoFile->size();
sizeToWrite = totalSize;
sendDate(makerSocket, tr("file#%1#%2").arg(totalSize).arg(curFileName));
} else {
qDebug() << "open file failed!";
}
}
else
{
return;//非服务器能接受处理的数据
}
}
void myTcp::sendDate(QTcpSocket *targetSocket, const QString &str)
{
int len = targetSocket->write(str.toUtf8(), str.length() + 1);
targetSocket->flush();
if(len > 0)
{
QString clientIp = targetSocket->peerAddress().toString();
}
}
void myTcp::slotSendFile(qint64 numBytes)
{
if(!isSendFile)
return;
QTcpSocket *makerSocket = static_cast<QTcpSocket *>(this->sender());
outBuf.resize(0);
if(sizeToWrite > 0 ) { //服务端还要写的字节数
outBuf = cryptoFile->read(qMin(sizeToWrite,loadSize)); //最大发送64KB的数据包
sizeToWrite -= (static_cast<int>(makerSocket->write(outBuf)));
outBuf.resize(0);
}
if(sizeToWrite == 0){
cryptoFile->close();
cryptoFile->remove();
file = NULL;
cryptoFile = NULL;
totalSize = 0;
sizeToWrite = 0;
isSendFile = false;
outBuf.resize(0);
QString clientIp = makerSocket->peerAddress().toString();
qDebug() << "send file to " << clientIp << " succeed.";
makerSocket->close();
}
}