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