libbnetapi: Add socket messenger class.
- Introduces new network API class BSocketMessenger, allowing one to send and receive BMessages across a network socket in a BMessenger-like fashion. Still very much WIP, hence currently not exposed via public headers. Based partly on previous work by Axel.
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2016, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef SOCKET_MESSENGER_H
|
||||||
|
#define SOCKET_MESSENGER_H
|
||||||
|
|
||||||
|
#include <Socket.h>
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
class BMessenger;
|
||||||
|
|
||||||
|
|
||||||
|
class BSocketMessenger {
|
||||||
|
public:
|
||||||
|
BSocketMessenger();
|
||||||
|
BSocketMessenger(
|
||||||
|
const BNetworkAddress& address,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
// adopt an existing already connected socket.
|
||||||
|
BSocketMessenger(const BSocket& socket);
|
||||||
|
virtual ~BSocketMessenger();
|
||||||
|
|
||||||
|
void Unset();
|
||||||
|
status_t SetTo(const BNetworkAddress& address,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
status_t SetTo(const BSocketMessenger& target,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
|
||||||
|
status_t InitCheck() const { return fInitStatus; }
|
||||||
|
|
||||||
|
const BNetworkAddress& Address() const { return fSocket.Peer(); }
|
||||||
|
|
||||||
|
virtual status_t SendMessage(const BMessage& message);
|
||||||
|
virtual status_t SendMessage(const BMessage& message,
|
||||||
|
BMessage& _reply,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
virtual status_t SendMessage(const BMessage& message,
|
||||||
|
BMessenger& replyTarget,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
|
||||||
|
// wait for unsolicited message on socket
|
||||||
|
virtual status_t ReceiveMessage(BMessage& _message,
|
||||||
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _SendMessage(const BMessage& message);
|
||||||
|
status_t _ReadMessage(BMessage& _message,
|
||||||
|
bigtime_t timeout);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BSocket fSocket;
|
||||||
|
status_t fInitStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SOCKET_MESSENGER_H
|
||||||
@@ -64,9 +64,10 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
|
|
||||||
AbstractSocket.cpp
|
AbstractSocket.cpp
|
||||||
DatagramSocket.cpp
|
DatagramSocket.cpp
|
||||||
Socket.cpp
|
|
||||||
SecureSocket.cpp
|
|
||||||
ProxySecureSocket.cpp
|
ProxySecureSocket.cpp
|
||||||
|
SecureSocket.cpp
|
||||||
|
Socket.cpp
|
||||||
|
SocketMessenger.cpp
|
||||||
|
|
||||||
# TODO: another add-on for file:// (a much simpler one)
|
# TODO: another add-on for file:// (a much simpler one)
|
||||||
FileRequest.cpp
|
FileRequest.cpp
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2011, Axel Dörfler, [email protected].
|
||||||
|
* Copyright 2016, Rene Gollent, [email protected].
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <SocketMessenger.h>
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
|
||||||
|
BSocketMessenger::BSocketMessenger()
|
||||||
|
:
|
||||||
|
fSocket(),
|
||||||
|
fInitStatus(B_NO_INIT)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSocketMessenger::BSocketMessenger(const BNetworkAddress& address,
|
||||||
|
bigtime_t timeout)
|
||||||
|
{
|
||||||
|
SetTo(address, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSocketMessenger::BSocketMessenger(const BSocket& socket)
|
||||||
|
:
|
||||||
|
fSocket(socket)
|
||||||
|
{
|
||||||
|
fInitStatus = socket.InitCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSocketMessenger::~BSocketMessenger()
|
||||||
|
{
|
||||||
|
Unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BSocketMessenger::Unset()
|
||||||
|
{
|
||||||
|
fSocket.Disconnect();
|
||||||
|
fInitStatus = B_NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::SetTo(const BNetworkAddress& address, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
return fInitStatus = fSocket.Connect(address, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::SetTo(const BSocketMessenger& target, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
return SetTo(target.Address(), timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::SendMessage(const BMessage& message)
|
||||||
|
{
|
||||||
|
return _SendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::SendMessage(const BMessage& message, BMessage& _reply,
|
||||||
|
bigtime_t timeout)
|
||||||
|
{
|
||||||
|
status_t error = _SendMessage(message);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return _ReadMessage(_reply, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::SendMessage(const BMessage& message,
|
||||||
|
BMessenger& replyTarget, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
BMessage reply;
|
||||||
|
status_t error = SendMessage(message, reply, timeout);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return replyTarget.SendMessage(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::ReceiveMessage(BMessage& _message, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
return _ReadMessage(_message, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::_SendMessage(const BMessage& message)
|
||||||
|
{
|
||||||
|
ssize_t flatSize = message.FlattenedSize();
|
||||||
|
flatSize += sizeof(ssize_t);
|
||||||
|
|
||||||
|
char* buffer = new(std::nothrow) char[flatSize];
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
ArrayDeleter<char> bufferDeleter(buffer);
|
||||||
|
*(ssize_t*)buffer = flatSize;
|
||||||
|
char* messageBuffer = buffer + sizeof(ssize_t);
|
||||||
|
status_t error = message.Flatten(messageBuffer, flatSize);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ssize_t size = fSocket.Write(buffer, flatSize);
|
||||||
|
if (size < 0)
|
||||||
|
return size;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BSocketMessenger::_ReadMessage(BMessage& _message, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
status_t error = fSocket.WaitForReadable(timeout);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ssize_t size = 0;
|
||||||
|
ssize_t readSize = fSocket.Read(&size, sizeof(ssize_t));
|
||||||
|
if (readSize < 0)
|
||||||
|
return readSize;
|
||||||
|
else if (readSize != sizeof(ssize_t))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (size <= 0)
|
||||||
|
return B_MISMATCHED_VALUES;
|
||||||
|
|
||||||
|
char* buffer = new(std::nothrow) char[size];
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
ArrayDeleter<char> bufferDeleter(buffer);
|
||||||
|
readSize = fSocket.Read(buffer, size);
|
||||||
|
if (readSize < 0)
|
||||||
|
return readSize;
|
||||||
|
else if (readSize != size)
|
||||||
|
return B_MISMATCHED_VALUES;
|
||||||
|
|
||||||
|
return _message.Unflatten(buffer);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user