Added an overlapped version to Socket

This commit is contained in:
Micke Prag 2010-06-14 08:21:12 +00:00
parent 8d2383eb5b
commit 53d1f16274
4 changed files with 319 additions and 217 deletions

View file

@ -15,9 +15,13 @@ class Socket : public QObject {
Q_OBJECT
public:
Socket(SOCKET_T socket);
Socket();
~Socket(void);
void connectToServer(const QString &serverName);
void disconnect();
void write(const TelldusService::Message &msg);
QByteArray readOverlapped();
QByteArray read();
bool connected() const;

View 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;
}

View file

@ -1,133 +1,133 @@
FIND_PACKAGE( Qt4 REQUIRED )
SET(QT_USE_QTNETWORK TRUE)
INCLUDE( ${QT_USE_FILE} )
IF(COMMAND cmake_policy)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
######## Non configurable options ########
SET( telldus-service_SRCS
TelldusCore.cpp
Manager.cpp
../common/Message.cpp
)
SET( telldus-service_HDRS
)
SET( telldus-service_MOC_HDRS
TelldusCore.h
Manager.h
MessageReceiver.h
Pipe.h
Socket.h
)
SET( telldus-service_LIBRARIES
${QT_LIBRARIES}
)
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/driver
${CMAKE_CURRENT_SOURCE_DIR}/../common
)
######## Configurable options for the platform ########
######## Platforms-specific, non configurable ########
SET( telldus-service_TARGET TelldusService )
IF (APPLE) #### Mac OS X ####
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
${COREFOUNDATION_LIBRARY}
${IOKIT_LIBRARY}
TelldusCoreLib
)
SET( telldus-service_SRCS
${telldus-service_SRCS}
main_unix.cpp
MessageReceiver_mac.cpp
MessageReceiverPrivate_mac.cpp
)
SET( telldus-service_MOC_HDRS
${telldus-service_MOC_HDRS}
MessageReceiverPrivate_mac.h
)
ELSEIF (WIN32) #### Windows ####
ADD_DEFINITIONS( -DUNICODE )
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
SET(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE"
)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/TelldusCoreLib.lib
)
SET( telldus-service_SRCS
${telldus-service_SRCS}
MessageReceiver_win.cpp
Pipe_win.cpp
Socket_win.cpp
main_win.cpp
TelldusService_win.cpp
)
SET( telldus-service_MOC_HDRS
${telldus-service_MOC_HDRS}
TelldusService_win.h
)
ELSE (APPLE) #### Linux ####
SET( telldus-service_SRCS
${telldus-service_SRCS}
MessageReceiver_unix.cpp
main_unix.cpp
)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
telldus-core-lib
)
ENDIF (APPLE)
######## QtService ########
IF (WIN32)
INCLUDE( ../../3rdparty/qtservice.cmake NO_POLICY_SCOPE )
SET( telldus-service_SRCS
${telldus-service_SRCS}
${qtservice_SRCS}
)
ENDIF(WIN32)
######## Configuring ########
QT4_WRAP_CPP( telldus-service_MOC_SRCS ${telldus-service_MOC_HDRS} )
ADD_EXECUTABLE(${telldus-service_TARGET}
${telldus-service_SRCS}
${telldus-service_MOC_SRCS}
${telldus-service_MOC_HDRS}
)
SET_SOURCE_FILES_PROPERTIES(${telldus-service_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
TARGET_LINK_LIBRARIES( ${telldus-service_TARGET} ${telldus-service_LIBRARIES} )
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
IF (APPLE)
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)
ELSEIF (UNIX)
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/TelldusCenter
)
ENDIF (APPLE)
FIND_PACKAGE( Qt4 REQUIRED )
SET(QT_USE_QTNETWORK TRUE)
INCLUDE( ${QT_USE_FILE} )
IF(COMMAND cmake_policy)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
######## Non configurable options ########
SET( telldus-service_SRCS
TelldusCore.cpp
Manager.cpp
../common/Message.cpp
)
SET( telldus-service_HDRS
)
SET( telldus-service_MOC_HDRS
TelldusCore.h
Manager.h
MessageReceiver.h
Pipe.h
../common/Socket.h
)
SET( telldus-service_LIBRARIES
${QT_LIBRARIES}
)
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/driver
${CMAKE_CURRENT_SOURCE_DIR}/../common
)
######## Configurable options for the platform ########
######## Platforms-specific, non configurable ########
SET( telldus-service_TARGET TelldusService )
IF (APPLE) #### Mac OS X ####
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
${COREFOUNDATION_LIBRARY}
${IOKIT_LIBRARY}
TelldusCoreLib
)
SET( telldus-service_SRCS
${telldus-service_SRCS}
main_unix.cpp
MessageReceiver_mac.cpp
MessageReceiverPrivate_mac.cpp
)
SET( telldus-service_MOC_HDRS
${telldus-service_MOC_HDRS}
MessageReceiverPrivate_mac.h
)
ELSEIF (WIN32) #### Windows ####
ADD_DEFINITIONS( -DUNICODE )
ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No
SET(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE"
)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/TelldusCoreLib.lib
)
SET( telldus-service_SRCS
${telldus-service_SRCS}
MessageReceiver_win.cpp
Pipe_win.cpp
../common/Socket_win.cpp
main_win.cpp
TelldusService_win.cpp
)
SET( telldus-service_MOC_HDRS
${telldus-service_MOC_HDRS}
TelldusService_win.h
)
ELSE (APPLE) #### Linux ####
SET( telldus-service_SRCS
${telldus-service_SRCS}
MessageReceiver_unix.cpp
main_unix.cpp
)
SET( telldus-service_LIBRARIES
${telldus-service_LIBRARIES}
telldus-core-lib
)
ENDIF (APPLE)
######## QtService ########
IF (WIN32)
INCLUDE( ../../3rdparty/qtservice.cmake NO_POLICY_SCOPE )
SET( telldus-service_SRCS
${telldus-service_SRCS}
${qtservice_SRCS}
)
ENDIF(WIN32)
######## Configuring ########
QT4_WRAP_CPP( telldus-service_MOC_SRCS ${telldus-service_MOC_HDRS} )
ADD_EXECUTABLE(${telldus-service_TARGET}
${telldus-service_SRCS}
${telldus-service_MOC_SRCS}
${telldus-service_MOC_HDRS}
)
SET_SOURCE_FILES_PROPERTIES(${telldus-service_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
TARGET_LINK_LIBRARIES( ${telldus-service_TARGET} ${telldus-service_LIBRARIES} )
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
IF (APPLE)
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)
ELSEIF (UNIX)
SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/TelldusCenter
)
ENDIF (APPLE)

View file

@ -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;
}