//*****************************************************************************
// RCF - Remote Call Framework
// Copyright (c) 2005. All rights reserved.
// Developed by Jarl Lindrud.
// Contact: jlindrud@hotmail.com .
//*****************************************************************************
#ifndef INCLUDE_RCF_TCPCLIENTTRANSPORT_HPP
#define INCLUDE_RCF_TCPCLIENTTRANSPORT_HPP
#include <utility> // std::make_pair
#include <RCF/AsyncFilter.hpp>
#include <RCF/ByteOrdering.hpp>
#include <RCF/ClientTransport.hpp>
#include <RCF/UsingBsdSockets.hpp>
namespace RCF {
//******************************************************
// nonblocking socket routines
int timedConnect(int timeoutMs, int fd, sockaddr *addr, int size);
// returns -2 for timeout, -1 for error, otherwise number of bytes sent (> 0)
int timedSend(int timeoutMs, int fd, const char *buffer, std::size_t length, int flags);
// returns -2 for timeout, -1 for error, 0 for peer closure, otherwise size of packet read
inline int timedRecv(int timeoutMs, int fd, char *buffer, std::size_t bufferLen, int flags);
class BsdRecvFunctor
{
public:
BsdRecvFunctor();
enum Status
{
Ok,
ConnectionReset,
SocketError,
TimeOut
};
void setFd(int fd);
int getFd();
void setEndTimeMs(unsigned int endTimeMs);
unsigned int getEndTimeMs();
Status getStatus();
void operator()(char *buffer, std::size_t bufferLen);
Filter::ReadFunction getReadFunction();
void setReadWriteCompletionCallback(Filter::ReadWriteCompletionCallback readWriteCompletionCallback);
private:
Filter::ReadWriteCompletionCallback readWriteCompletionCallback;
int fd;
unsigned int endTimeMs;
Status status;
};
class BsdSendFunctor
{
public:
BsdSendFunctor();
enum Status
{
Ok,
SocketError,
TimeOut
};
void setFd(int fd);
int getFd();
void setEndTimeMs(unsigned int endTimeMs);
unsigned int getEndTimeMs();
void operator()(const char *buffer, std::size_t bufferLen);
Filter::WriteFunction getWriteFunction();
void setReadWriteCompletionCallback(Filter::ReadWriteCompletionCallback readWriteCompletionCallback);
private:
Filter::ReadWriteCompletionCallback readWriteCompletionCallback;
int fd;
unsigned int endTimeMs;
Status status;
};
class TcpClientTransport;
typedef boost::shared_ptr<TcpClientTransport> TcpClientTransportPtr;
class TcpClientTransport : public I_ClientTransport
{
public:
TcpClientTransport::TcpClientTransport(const TcpClientTransport &rhs);
TcpClientTransport(const std::string &ip, int port);
TcpClientTransport(sockaddr_in remoteAddr);
TcpClientTransport(int fd);
~TcpClientTransport();
std::auto_ptr<I_ClientTransport> clone() const;
EndpointPtr getEndpointPtr() const;
int connect(unsigned int timeoutMs);
// return -1 for error (including timeout), 1 for ok
int send(const std::string &data, unsigned int timeoutMs);
// return -1 for error (including timeout), otherwise bufferLen
int timedReceive(char *buffer, std::size_t bufferLen);
// returns -2 for timeout, .1 for error, 0 for peer closure, 1 for ok
int receive(std::string &data, unsigned int timeoutMs);
typedef boost::function1<void, int &> CloseFunctor;
void setCloseFunctor(CloseFunctor closeFunctor);
void setRemoteAddr(const sockaddr_in &remoteAddr);
const sockaddr_in &getRemoteAddr();
void close();
bool isConnected();
int releaseFd();
int getFd();
void setTransportFilters(const std::vector<FilterPtr> &filters);
void connectTransportFilters();
void onReadWriteCompleted(std::size_t bytes, int error);
private:
sockaddr_in mRemoteAddr;
std::string ip;
int port;
int fd;
bool own;
std::size_t mBytesTransferred;
int mError;
boost::shared_ptr< CloseFunctor > mCloseFunctor;
std::vector<FilterPtr> mTransportFilters;
BsdSendFunctor sendFunctor;
BsdRecvFunctor recvFunctor;
};
}
#endif // ! INCLUDE_RCF_TCPCLIENTTRANSPORT_HPP