Added an overlapped version to Socket
This commit is contained in:
parent
8d2383eb5b
commit
53d1f16274
4 changed files with 319 additions and 217 deletions
|
@ -15,9 +15,13 @@ class Socket : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Socket(SOCKET_T socket);
|
Socket(SOCKET_T socket);
|
||||||
|
Socket();
|
||||||
~Socket(void);
|
~Socket(void);
|
||||||
|
|
||||||
|
void connectToServer(const QString &serverName);
|
||||||
|
void disconnect();
|
||||||
void write(const TelldusService::Message &msg);
|
void write(const TelldusService::Message &msg);
|
||||||
|
QByteArray readOverlapped();
|
||||||
QByteArray read();
|
QByteArray read();
|
||||||
|
|
||||||
bool connected() const;
|
bool connected() const;
|
182
telldus-core/telldus-service/common/Socket_win.cpp
Normal file
182
telldus-core/telldus-service/common/Socket_win.cpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#include "Socket.h"
|
||||||
|
//#include "TelldusCore.h"
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
class SocketPrivate {
|
||||||
|
public:
|
||||||
|
SOCKET_T hPipe;
|
||||||
|
HANDLE event;
|
||||||
|
bool connected;
|
||||||
|
};
|
||||||
|
|
||||||
|
Socket::Socket(SOCKET_T socket)
|
||||||
|
{
|
||||||
|
d = new SocketPrivate;
|
||||||
|
d->hPipe = socket;
|
||||||
|
d->event = INVALID_HANDLE_VALUE;
|
||||||
|
d->connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Socket() {
|
||||||
|
d = new SocketPrivate;
|
||||||
|
d->hPipe = INVALID_HANDLE_VALUE;
|
||||||
|
d->event = INVALID_HANDLE_VALUE;
|
||||||
|
d->connected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::~Socket(void) {
|
||||||
|
if (d->connected) {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
if (d->hPipe != INVALID_HANDLE_VALUE) {
|
||||||
|
/*TelldusCore::logMessage("Flush file");
|
||||||
|
//FlushFileBuffers(d->hPipe);
|
||||||
|
TelldusCore::logMessage("Cancel Sync");
|
||||||
|
CancelSynchronousIo(d->thread);
|
||||||
|
TelldusCore::logMessage("Disconnect named pipe");*/
|
||||||
|
//DisconnectNamedPipe(d->hPipe);
|
||||||
|
//TelldusCore::logMessage("CloseHandle");
|
||||||
|
CloseHandle(d->hPipe);
|
||||||
|
//TelldusCore::logMessage("Done");
|
||||||
|
}
|
||||||
|
if (d->event != INVALID_HANDLE_VALUE) {
|
||||||
|
CloseHandle(d->event);
|
||||||
|
}
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::connectToServer(const QString &server) {
|
||||||
|
DWORD dwMode;
|
||||||
|
bool fSuccess = false;
|
||||||
|
|
||||||
|
d->event = CreateEvent(
|
||||||
|
NULL, // default security attribute
|
||||||
|
TRUE, // manual-reset event
|
||||||
|
TRUE, // initial state = signaled
|
||||||
|
NULL); // unnamed event object
|
||||||
|
|
||||||
|
if (d->event == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString name = QString("\\\\.\\pipe\\%1").arg(server);
|
||||||
|
d->hPipe = CreateFile(
|
||||||
|
(const wchar_t *)name.utf16(), // pipe name
|
||||||
|
GENERIC_READ | // read and write access
|
||||||
|
GENERIC_WRITE,
|
||||||
|
0, // no sharing
|
||||||
|
NULL, // default security attributes
|
||||||
|
OPEN_EXISTING, // opens existing pipe
|
||||||
|
FILE_FLAG_OVERLAPPED, // default attributes
|
||||||
|
NULL); // no template file
|
||||||
|
|
||||||
|
if (d->hPipe == INVALID_HANDLE_VALUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwMode = PIPE_READMODE_MESSAGE;
|
||||||
|
fSuccess = SetNamedPipeHandleState(
|
||||||
|
d->hPipe, // pipe handle
|
||||||
|
&dwMode, // new pipe mode
|
||||||
|
NULL, // don't set maximum bytes
|
||||||
|
NULL); // don't set maximum time
|
||||||
|
|
||||||
|
if (!fSuccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::disconnect() {
|
||||||
|
d->connected = false;
|
||||||
|
if (d->event != INVALID_HANDLE_VALUE) {
|
||||||
|
SetEvent(d->event);
|
||||||
|
}
|
||||||
|
emit disconnected();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::write(const TelldusService::Message &msg) {
|
||||||
|
DWORD bytesWritten = 0;
|
||||||
|
//TelldusCore::logMessage(QString("Sending: %1").arg(QString(msg)));
|
||||||
|
if (WriteFile(d->hPipe, msg.data(), msg.length(), &bytesWritten, NULL)) {
|
||||||
|
//TelldusCore::logMessage(QString("Done sending"));
|
||||||
|
//FlushFileBuffers(d->hPipe);
|
||||||
|
} else {
|
||||||
|
//TelldusCore::logMessage("Pipe disconnected");
|
||||||
|
d->connected = false;
|
||||||
|
emit disconnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Socket::readOverlapped() {
|
||||||
|
char buf[BUFSIZE];
|
||||||
|
int result;
|
||||||
|
DWORD cbBytesRead = 0;
|
||||||
|
OVERLAPPED oOverlap;
|
||||||
|
oOverlap.hEvent = d->event;
|
||||||
|
bool fSuccess = false;
|
||||||
|
|
||||||
|
memset(&buf, 0, BUFSIZE);
|
||||||
|
|
||||||
|
if (!d->connected) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadFile( d->hPipe, &buf, sizeof(char)*BUFSIZE, &cbBytesRead, &oOverlap);
|
||||||
|
|
||||||
|
result = WaitForSingleObject(oOverlap.hEvent, 10000);
|
||||||
|
if (result == WAIT_TIMEOUT) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, false);
|
||||||
|
if (!fSuccess) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Socket::read() {
|
||||||
|
char buf[BUFSIZE];
|
||||||
|
DWORD cbBytesRead = 0;
|
||||||
|
bool fSuccess = false;
|
||||||
|
|
||||||
|
//TelldusCore::logMessage("= Start read");
|
||||||
|
|
||||||
|
//If we have a connection from a client this function will never complete
|
||||||
|
//So while the is connected clients this service cannot exit properly.
|
||||||
|
//We should find a way to make this function fail in the destructor to this
|
||||||
|
//class.
|
||||||
|
fSuccess = ReadFile(
|
||||||
|
d->hPipe, // handle to pipe
|
||||||
|
&buf, // buffer to receive data
|
||||||
|
BUFSIZE*sizeof(char), // size of buffer
|
||||||
|
&cbBytesRead, // number of bytes read
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (fSuccess) {
|
||||||
|
//TelldusCore::logMessage(QString("= Done read: %1").arg(buf));
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
} else {
|
||||||
|
if (cbBytesRead == 0) {
|
||||||
|
int err = GetLastError();
|
||||||
|
if (err == ERROR_BROKEN_PIPE) {
|
||||||
|
//TelldusCore::logMessage("Broken Pipe");
|
||||||
|
} else if (err == ERROR_INVALID_HANDLE) {
|
||||||
|
//TelldusCore::logMessage("Invalid handle");
|
||||||
|
} else {
|
||||||
|
//TelldusCore::logMessage("Unknown error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TelldusCore::logMessage(QString("= Failed read %1").arg(GetLastError()));
|
||||||
|
d->connected = false;
|
||||||
|
emit disconnected();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::connected() const {
|
||||||
|
return d->connected;
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ SET( telldus-service_MOC_HDRS
|
||||||
Manager.h
|
Manager.h
|
||||||
MessageReceiver.h
|
MessageReceiver.h
|
||||||
Pipe.h
|
Pipe.h
|
||||||
Socket.h
|
../common/Socket.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( telldus-service_LIBRARIES
|
SET( telldus-service_LIBRARIES
|
||||||
|
@ -73,7 +73,7 @@ ELSEIF (WIN32) #### Windows ####
|
||||||
${telldus-service_SRCS}
|
${telldus-service_SRCS}
|
||||||
MessageReceiver_win.cpp
|
MessageReceiver_win.cpp
|
||||||
Pipe_win.cpp
|
Pipe_win.cpp
|
||||||
Socket_win.cpp
|
../common/Socket_win.cpp
|
||||||
main_win.cpp
|
main_win.cpp
|
||||||
TelldusService_win.cpp
|
TelldusService_win.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
#include "Socket.h"
|
|
||||||
#include "TelldusCore.h"
|
|
||||||
#include <QMutex>
|
|
||||||
|
|
||||||
class SocketPrivate {
|
|
||||||
public:
|
|
||||||
SOCKET_T hPipe;
|
|
||||||
bool connected;
|
|
||||||
};
|
|
||||||
|
|
||||||
Socket::Socket(SOCKET_T socket)
|
|
||||||
{
|
|
||||||
d = new SocketPrivate;
|
|
||||||
d->hPipe = socket;
|
|
||||||
d->connected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket::~Socket(void) {
|
|
||||||
/*TelldusCore::logMessage("Flush file");
|
|
||||||
//FlushFileBuffers(d->hPipe);
|
|
||||||
TelldusCore::logMessage("Cancel Sync");
|
|
||||||
CancelSynchronousIo(d->thread);
|
|
||||||
TelldusCore::logMessage("Disconnect named pipe");
|
|
||||||
//DisconnectNamedPipe(d->hPipe); */
|
|
||||||
TelldusCore::logMessage("CloseHandle");
|
|
||||||
CloseHandle(d->hPipe);
|
|
||||||
TelldusCore::logMessage("Done");
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::write(const TelldusService::Message &msg) {
|
|
||||||
DWORD bytesWritten = 0;
|
|
||||||
TelldusCore::logMessage(QString("Sending: %1").arg(QString(msg)));
|
|
||||||
if (WriteFile(d->hPipe, msg.data(), msg.length(), &bytesWritten, NULL)) {
|
|
||||||
TelldusCore::logMessage(QString("Done sending"));
|
|
||||||
//FlushFileBuffers(d->hPipe);
|
|
||||||
} else {
|
|
||||||
TelldusCore::logMessage("Pipe disconnected");
|
|
||||||
d->connected = false;
|
|
||||||
emit disconnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray Socket::read() {
|
|
||||||
char buf[BUFSIZE];
|
|
||||||
DWORD cbBytesRead = 0;
|
|
||||||
|
|
||||||
TelldusCore::logMessage("= Start read");
|
|
||||||
|
|
||||||
//If we have a connection from a client this function will never complete
|
|
||||||
//So while the is connected clients this service cannot exit properly.
|
|
||||||
//We should find a way to make this function fail in the destructor to this
|
|
||||||
//class.
|
|
||||||
bool fSuccess = ReadFile(
|
|
||||||
d->hPipe, // handle to pipe
|
|
||||||
&buf, // buffer to receive data
|
|
||||||
BUFSIZE*sizeof(char), // size of buffer
|
|
||||||
&cbBytesRead, // number of bytes read
|
|
||||||
NULL); // not overlapped I/O
|
|
||||||
|
|
||||||
if (fSuccess) {
|
|
||||||
TelldusCore::logMessage(QString("= Done read: %1").arg(buf));
|
|
||||||
return buf;
|
|
||||||
} else {
|
|
||||||
if (cbBytesRead == 0) {
|
|
||||||
int err = GetLastError();
|
|
||||||
if (err == ERROR_BROKEN_PIPE) {
|
|
||||||
TelldusCore::logMessage("Broken Pipe");
|
|
||||||
} else if (err == ERROR_INVALID_HANDLE) {
|
|
||||||
TelldusCore::logMessage("Invalid handle");
|
|
||||||
} else {
|
|
||||||
TelldusCore::logMessage("Unknown error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TelldusCore::logMessage(QString("= Failed read %1").arg(GetLastError()));
|
|
||||||
d->connected = false;
|
|
||||||
emit disconnected();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Socket::connected() const {
|
|
||||||
return d->connected;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue