原文链接:https://blog.csdn.net/yuanrxdu/article/details/78454426
最近在复习udp时想到老师曾经所说的RUDP,在网上查询了一些资料尝试写了一下。本人菜鸡,如有不足还请指正。
这是makefile文件
ReliableSocket.o : ReliableSocket.cpp ReliableSocket.h Segment.h Timer.h DatagramPacket.h ReliableSocketOutputStream.h ReliableSocketProfile.h ReliableSocketListener.h ReliableSocketStateListener.h
g++ -c ReliableSocket.cpp
Segment.o : Segment.cpp Segment.h
g++ -c Segment.cpp
Timer.o : Timer.cpp Thread.h Timer.h
g++ -c Timer.cpp
Thread.o : Thread.cpp Thread.h
g++ -c Thread.cpp -lpthread
DatagramPacket.o : DatagramPacket.cpp DatagramPacket.h
g++ -c DatagramPacket.cpp
ReliableSocketOutputStream.o : ReliableSocketOutputStream.cpp ReliableSocketOutputStream.h ReliableSocket.h
g++ -c ReliableSocketOutputStream.cpp
ReliableSocketProfile.o : ReliableSocketProfile.cpp ReliableSocketProfile.h
g++ -c ReliableSocketProfile.cpp
.PHONY:clean
clean:
rm ReliableSocket ReliableSocket.o Segment.o Timer.o DatagramPacket.o ReliableSocketOutputStream.o ReliableSocketProfile.o
#ifndef RELIABLESOCKET_H_
#define RELIABLESOCKET_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Segment.h"
#include "Timer.h"
#include "Thread.h"
#include "DatagramPacket.h"
#include "ReliableSocketOutputStream.h"
#include "ReliableSocketProfile.h"
#include "ReliableSocketListener.h"
#include "ReliableSocketStateListener.h"
using namespace __gnu_cxx;
class ReliableSocketOutputStream;
class ReliableSocketInputStream;
class ReliableServerSocket;
class ReliableSocketListener;
class LogTimeMM;
class Counters;
class ShutdownHook;
class ReliableClientSocket;
class ReliableSocket
{
public:
ReliableSocket();
ReliableSocket(ReliableSocketProfile *profile);
ReliableSocket(struct in_addr address,int port,struct in_addr localAddr,int localPort);
ReliableSocket(struct sockaddr_in inetAddr,struct sockaddr_in localAddr);
ReliableSocket(int dgram_sock);
ReliableSocket(int dgram_sock,ReliableSocketProfile *profile);
virtual ~ReliableSocket(){}
void bind_sock(struct sockaddr *bindport,int addrlen);
void connect_Socket(struct sockaddr *endpoint, int timeout = 0);
struct in_addr getInetAddress();
struct sockaddr *_endpoint;
friend class ReliableSocketInputStream;
friend class Counters;
friend class ReliableSocketThread;
friend class NullSegmentTimerTask;
friend class RetransmissionTimerTask;
friend class CumulativeAckTimerTask;
friend class KeepAliveTimerTask;
friend class ShutdownHook;
ushort getPort();
ReliableSocketInputStream& getInputStream();
ReliableSocketOutputStream& getOutputStream();
void closeSock();
void setSoTimeout(int timeout);
void setSendBufferSize(int size);
void setReceiveBufferSize(int size);
void setKeepAlive(bool on);
void shutdownInput();
void shutdownOutput();
bool getKeepAlive();
bool isConnected();
bool isClosed();
bool isInputShutdown();
bool isOutputShutdown();
int getSendBufferSize();
int getReceiveBufferSize();
void reset(ReliableSocketProfile *profile=NULL);
void write(unsigned char b[], int off, int len);
int read(unsigned char b[],int off,int len);
void addListener(ReliableSocketListener *listener);
void removeListener(ReliableSocketListener *listener);
void addStateListener(ReliableSocketStateListener *stateListener);
void removeStateListener(ReliableSocketStateListener *stateListener);
void init(int &sock,ReliableSocketProfile *profile);
protected:
//函数成员
void closeSocket();
void closeImpl();
void sendSegment(Segment *s);
void retransmitSegment(Segment segment);
void handleSYNSegment(SYNSegment *segment);
void handleEAKSegment(EAKSegment *segment);
void handleSegment(Segment segment);
void sendAndQueueSegment(Segment *segment);
void checkAndSetAck(Segment s);
void checkAndGetAck(Segment segment);
void checkRecvQueues();
void sendSegmentImpl(Segment *s);
void sendAck();
void sendExtendedAck();
void sendSingleAck();
void connectionOpened();
void connectionRefused();
void connectionClosed();
void connectionFailure();
void connectionReset();
Segment receiveSegment();
virtual Segment* receiveSegmentImpl();
static int nextSequenceNumber(int seqn);
int compareSequenceNumbers(int seqn, int aseqn);
//数据成员
pthread_mutex_t unackedSentQueue;
pthread_cond_t cond;
Counters *_counters;
list _unackedSentQueue;
list _outSeqRecvQueue;
list _inSeqRecvQueue;
int _state;
private:
ReliableClientSocket addClientSocket(struct sockaddr_in *my_addr);
ReliableClientSocket removeClientSocket(struct sockaddr_in *my_addr);
unsigned char *_recvbuffer;
bool _closed;
bool _connected;
bool _reset;
bool _keepAlive;
int _sock;
int _timeout;
bool _shutIn;
bool _shutOut;
//声明不同的互斥锁
pthread_mutex_t mutex;
pthread_mutex_t _closeLock;
pthread_mutex_t _recvQueueLock;
pthread_mutex_t _resetLock;
pthread_mutex_t listenerLock; //_listeners
pthread_mutex_t stateLock; //_stateListeners
pthread_mutex_t _inSeqRecvLock; //_inReqRecvQueue
list _listeners;
list _stateListeners;
ShutdownHook *_shutdownHook;
ReliableSocketProfile *_profile;
ReliableSocketInputStream *_in;
ReliableSocketOutputStream *_out;
Thread *_sockThread;
int _sendBufferSize;
int _recvBufferSize;
//待写
Timer *_nullSegmentTimer;
Timer *_retransmissionTimer;
Timer *_cumulativeAckTimer;
Timer *_keepAliveTimer;
static const int MAX_SEQUENCE_NUMBER;
static const int CLOSED;
static const int SYN_RCVD;
static const int SYN_SENT;
static const int ESTABLISHED;
static const int CLOSE_WAIT;
};
//class Counters
class Counters
{
public:
Counters(){}
~Counters(){}
int nextSequenceNumber();
int setSequenceNumber(int n);
int setLastInSequence(int n);
int getLastInSequence();
int getCumulativeAckCounter();
int getAndResetCumulativeAckCounter();
int getOutOfSequenceCounter();
int getAndResetOutOfSequenceCounter();
int getOutstandingSegsCounter();
int getAndResetOutstandingSegsCounter();
void incCumulativeAckCounter();
void incOutOfSequenceCounter();
void incOutstandingSegsCounter();
void reset();
private:
int _seqn;
int _lastInSequence;
int _cumAckCounter;
int _outOfSeqCounter;
int _outSegsCounter;
};
//ReliableSocketThread
class ReliableSocketThread:Thread
{
ReliableSocketThread();
void run();
};
class NullSegmentTimerTask:Runnable
{
void run();
};
class RetransmissionTimerTask:Runnable
{
void run();
};
class CumulativeAckTimerTask:Runnable
{
void run();
};
class KeepAliveTimerTask:Runnable
{
void run();
};
class ShutdownHook:Thread
{
public:
ShutdownHook():name("shutdown hook"){}
void run();
private:
std::string name;
};
//ReliableSocketInputStream
class ReliableSocketInputStream
{
public:
ReliableSocketInputStream(ReliableSocket *sock);
int read();
int read(unsigned char b[]);
int read(unsigned char b[],int off,int len);
int available();
//bool markSupported(){return false;}
void close(){_sock->shutdownInput();} //非法使用
int readImpl();
private:
ReliableSocket *_sock;
unsigned char *_buf;
int _pos;
int _count;
pthread_mutex_t mutex;
};
//ReliableServerSocket
class ReliableSocketStateListener;
class ReceiverThread;
typedef long long int64;
class ReliableServerSocket
{
public:
ReliableServerSocket(struct in_addr *Inetaddr=NULL,int port=0,int backlog=0);
ReliableServerSocket(int sockfd,int backlog);
ReliableSocket accept();
void bindSock(struct sockaddr_in *my_addr, int backlog=0);
void closeServSock();
bool isClosed(){return _closed;}
void setSoTimeout(int timeout);
//int getSoTimeout(){return _timeout;}
ReliableClientSocket* addClientSocket(struct sockaddr_in my_addr);
ReliableClientSocket* removeClientSocket(struct sockaddr_in my_addr);
private:
friend class ReceiverThread;
friend class ReliableClientSocket;
friend class StateListener;
ReceiverThread *thread;
int isbind;
int _serverSock;
int _timeout;
int _backlogSize;
bool _closed;
list *_backlog;
//hash_map _clientSockTable;
//vector _clientSockTable;
ReliableSocketStateListener *_stateListener;
static const int DEFAULT_BACKLOG_SIZE;
//互斥锁
pthread_mutex_t _backLock; //_backlog.
pthread_mutex_t _queueLock;
pthread_mutex_t _clientSockLock; //clientSockTable
pthread_cond_t cond;
};
//获取当前时间以毫秒形式返回
class LogTimeMM
{
public:
static int64 getSystemTime()
{
struct timeval tv; //获取一个时间结构
gettimeofday(&tv, NULL); //获取当前时间
int64 t = tv.tv_sec;
t*=1000;
t+=tv.tv_usec/1000;
return t;
}
};
class ReceiverThread:public Thread
{
public:
ReceiverThread(Runnable *iTarget):Thread (iTarget){}
void run();
};
class ReliableClientSocket:public ReliableSocket
{
public:
ReliableClientSocket(int sockfd,struct sockaddr_in *endpoint):ReliableSocket(sockfd)
{
_endpoint = (sockaddr*)endpoint;
}
void segmentReceived(Segment *s);
protected:
void init(int sockfd,ReliableSocketProfile *profile);
Segment* receiveSegmentImpl();
void closeSocket();
private:
list *_queue;
pthread_mutex_t _queueLock;
pthread_cond_t childCond;
};
class StateListener:public ReliableSocketStateListener
{
public:
void connectionOpened(ReliableSocket *sock){}
void connectionRefused(ReliableSocket *sock){}
void connectionClosed(ReliableSocket *sock){}
void connectionFailure(ReliableSocket *sock){}
void connectionReset(ReliableSocket *sock){}
};
#endif //_RELIABLESOCKET_H_
#include "ReliableSocket.h"
using namespace std;
//const variable
const int ReliableSocket::MAX_SEQUENCE_NUMBER = 255;
const int ReliableSocket::CLOSED = 0;
const int ReliableSocket::SYN_RCVD = 1;
const int ReliableSocket::SYN_SENT = 2;
const int ReliableSocket::ESTABLISHED = 3;
const int ReliableSocket::CLOSE_WAIT = 4;
//construction function
ReliableSocket::ReliableSocket()
{
ReliableSocket(new ReliableSocketProfile());
}
ReliableSocket::ReliableSocket(ReliableSocketProfile *profile)
{
int sfd;
sfd=socket(AF_INET, SOCK_DGRAM, 0);
ReliableSocket(sfd, profile);
}
ReliableSocket::ReliableSocket(struct in_addr address, int port,struct in_addr localAddr, int localPort)
{
struct sockaddr_in inetAddr;
struct sockaddr_in remoteAddr;
inetAddr.sin_port = htons(port);
inetAddr.sin_addr.s_addr = address.s_addr;
remoteAddr.sin_port = htons(localPort);
remoteAddr.sin_addr.s_addr = address.s_addr;
ReliableSocket(inetAddr, remoteAddr);
}
ReliableSocket::ReliableSocket(struct sockaddr_in inetAddr,struct sockaddr_in localAddr)
{
struct sockaddr_in remoteAddr;
int _sfd;
_sfd=socket(AF_INET,SOCK_DGRAM,0);
remoteAddr.sin_port=htons(localAddr.sin_port);
remoteAddr.sin_addr.s_addr=localAddr.sin_addr.s_addr;
ReliableSocket(_sfd,new ReliableSocketProfile());
connect_Socket((struct sockaddr*)&inetAddr);
}
ReliableSocket::ReliableSocket(int dgram_sock)
{
ReliableSocket(dgram_sock,new ReliableSocketProfile());
}
ReliableSocket::ReliableSocket(int dgram_sock,ReliableSocketProfile *profile)
{
if(dgram_sock == -1)
cout<<"dgram_sock"<maxSegmentSize()-Segment::RUDP_HEADER_LEN)*32;
_recvBufferSize=(_profile->maxSegmentSize()-Segment::RUDP_HEADER_LEN)*32;
_sockThread->start();
}
void ReliableSocket::bind_sock(struct sockaddr *bindpoint,int addrlen)
{
bind(_sock, bindpoint,sizeof(struct sockaddr));
}
void ReliableSocket::connect_Socket(struct sockaddr *endpoint,int timeout)
{
if (endpoint == NULL)
{
cout<<"connect:The address can't be null"<setSequenceNumber(rand()%MAX_SEQUENCE_NUMBER),
_profile->maxOutstandingSegs(),
_profile->maxSegmentSize(),
_profile->retransmissionTimeout(),
_profile->cumulativeAckTimeout(),
_profile->nullSegmentTimeout(),
_profile->maxRetrans(),
_profile->maxCumulativeAcks(),
_profile->maxOutOfSequence(),
_profile->maxAutoReset());
sendAndQueueSegment(syn);
bool timedout = false;
pthread_mutex_lock(&mutex);
if (!isConnected()){
try{
if (timeout == 0)
pthread_cond_wait(&cond, &mutex);
else{
int64 startTime = LogTimeMM::getSystemTime();
pthread_cond_wait(&cond, &mutex);
if (LogTimeMM::getSystemTime()-startTime >= timeout)
timedout = true;
}
}
catch(...){
cout<<"there is a exception!"<reset();
_retransmissionTimer->cancel();
switch(_state){
case SYN_SENT:
{
connectionRefused();
_state = CLOSED;
if (timedout)
{
cout<<"Socket Timedout Exception:Connection refused"<sin_addr;
}
ushort ReliableSocket::getPort()
{
if(!isConnected())
return 0;
return ((struct sockaddr_in *)_endpoint)->sin_port;
}
ReliableSocketInputStream& ReliableSocket::getInputStream()
{
if (isClosed())
cout<<"Socket is closed"<nextSequenceNumber()));
closeImpl();
break;
case CLOSED:
_retransmissionTimer->destroy();
_cumulativeAckTimer->destroy();
_keepAliveTimer->destroy();
_nullSegmentTimer->destroy();
close(_sock);
break;
}
_closed = true;
_state = CLOSED;
pthread_mutex_lock(&unackedSentQueue);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&unackedSentQueue);
pthread_mutex_lock(&_inSeqRecvLock);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&_inSeqRecvLock);
}
inline bool ReliableSocket::isConnected()
{
return _connected;
}
inline bool ReliableSocket::isClosed()
{
return _closed;
}
/*void ReliableSocket::setSoTimeout(int timeout)
{
if (timeout<0)
cout<<"Timeout<0"<0))
cout<<"negative receive size!"<0))
cout<<"negative send size"<schedule(_profile->nullSegmentTimeout()*6,_profile->nullSegmentTimeout()*6);
else
_keepAliveTimer->cancel();
}
}
bool ReliableSocket::getKeepAlive()
{
if(isClosed())
cout<<"Socket is closed!"<nextSequenceNumber()));
lc=pthread_mutex_lock(&unackedSentQueue);
while(!_unackedSentQueue.empty())
{
pthread_cond_wait(&cond, &unackedSentQueue);
}
lc=pthread_mutex_unlock(&unackedSentQueue);
rc=pthread_mutex_unlock(&_resetLock);
connectionReset();
if (profile!=NULL)
_profile=profile;
_state = SYN_SENT;
srand((unsigned)time(NULL));
Segment *syn=new SYNSegment(_counters->setSequenceNumber(rand()%MAX_SEQUENCE_NUMBER),
_profile->maxOutstandingSegs(),
_profile->maxSegmentSize(),
_profile->retransmissionTimeout(),
_profile->cumulativeAckTimeout(),
_profile->nullSegmentTimeout(),
_profile->maxRetrans(),
_profile->maxCumulativeAcks(),
_profile->maxOutOfSequence(),
_profile->maxAutoReset());
sendAndQueueSegment(syn);
}
void ReliableSocket::write(unsigned char b[], int off, int len)
{
if (isClosed())
cout<<"Socket is closed!"<maxSegmentSize()-Segment::RUDP_HEADER_LEN,len-totalBytes);
sendAndQueueSegment(new DATSegment(ReliableSocket::_counters->nextSequenceNumber(),ReliableSocket::_counters->getLastInSequence(),b,off+totalBytes,writeBytes));
totalBytes += writeBytes;
pthread_mutex_lock(&_resetLock);
}
}
int ReliableSocket::read(unsigned char b[],int off,int len)
{
int totalBytes = 0;
pthread_mutex_lock(&_recvQueueLock);
while(true)
{
while(_inSeqRecvQueue.empty())
{
if (isClosed())
cout<<"Socket is closed!"<= _timeout))
cout<<"timeout"<::iterator it;
for(it = _inSeqRecvQueue.begin(); it!=_inSeqRecvQueue.end();)
{
Segment s = (Segment)(*++it);
if (typeid(s) == typeid(RSTSegment))
{
_inSeqRecvQueue.erase(it);
break;
}
else if (typeid(s) == typeid(FINSegment))
{
if(totalBytes<=0){
_inSeqRecvQueue.erase(it);
return -1;
}
break;
}
else if(typeid(s) == typeid(DATSegment))
{
unsigned char *data = ((DATSegment*)&s)->getData();
if(sizeof(data)+totalBytes>len)
{
if (totalBytes<=0)
cout<<"insufficient buffer space"<0)
return totalBytes;
}
pthread_mutex_unlock(&_recvQueueLock);
}
void ReliableSocket::addListener(ReliableSocketListener *listener)
{
int rc;
if(listener == NULL)
cout<<"listener"<::iterator iter = find(_listeners.begin(),_listeners.end(),listener);
if (iter == _listeners.end())
_listeners.push_back(listener);
rc = pthread_mutex_unlock(&listenerLock);
}
void ReliableSocket::removeListener(ReliableSocketListener *listener)
{
int rc;
if (listener ==NULL)
cout<<"listener"<::iterator iter = find(_listeners.begin(),_listeners.end(),listener);
if (iter != _listeners.end())
_listeners.erase(iter);
rc = pthread_mutex_unlock(&listenerLock);
}
void ReliableSocket::addStateListener(ReliableSocketStateListener *stateListener)
{
int rc;
if (stateListener == NULL)
cout<<"stateListener"<::iterator iter = find(_stateListeners.begin(),_stateListeners.end(),stateListener);
if (iter == _stateListeners.end())
_stateListeners.push_back(stateListener);
rc=pthread_mutex_lock(&stateLock);
}
void ReliableSocket::removeStateListener(ReliableSocketStateListener *stateListener)
{
int rc;
if (stateListener == NULL)
cout<<"stateListener"<::iterator iter = find(_stateListeners.begin(),_stateListeners.end(),stateListener);
if (iter != _stateListeners.end())
_stateListeners.erase(iter);
rc=pthread_mutex_lock(&stateLock);
}
void ReliableSocket::sendSegment(Segment *s)
{
if (typeid(*s) == typeid(DATSegment) || typeid(*s) == typeid(RSTSegment) ||
typeid(*s) == typeid(FINSegment) || typeid(*s) == typeid(NULSegment))
checkAndSetAck(*s);
if (typeid(*s) == typeid(DATSegment)||typeid(*s) == typeid(RSTSegment)||typeid(*s) == typeid(FINSegment))
_nullSegmentTimer->reset();
sendSegmentImpl(s);
}
Segment ReliableSocket::receiveSegment()
{
Segment *s;
s=receiveSegmentImpl();
if (s != NULL)
{
if (typeid(s) == typeid(DATSegment) || typeid(s) == typeid(RSTSegment) ||
typeid(s) == typeid(FINSegment) || typeid(s) == typeid(NULSegment) || typeid(s) == typeid(SYNSegment))
ReliableSocket::_counters->incCumulativeAckCounter();
if (_keepAlive)
_keepAliveTimer->reset();
}
return *s;
}
void ReliableSocket::sendAndQueueSegment(Segment *segment)
{
int rc;
rc = pthread_mutex_lock(&unackedSentQueue);
while( _unackedSentQueue.size() >= 32 || _counters->getOutstandingSegsCounter() > _profile->maxOutstandingSegs()){
pthread_cond_wait(&cond, &unackedSentQueue);
}
_counters->incOutstandingSegsCounter();
_unackedSentQueue.push_back(*segment);
rc = pthread_mutex_unlock(&unackedSentQueue);
if (_closed)
cout<<"Socket is closed"<isIdle())
_retransmissionTimer->schedule(ReliableSocket::_profile->retransmissionTimeout(),ReliableSocket::_profile->retransmissionTimeout());
}
sendSegment(segment);
if (typeid(*segment) == typeid(DATSegment))
{
pthread_mutex_lock(&listenerLock);
list::iterator it = _listeners.begin();
while(it != _listeners.end())
{
ReliableSocketListener *l = *(++it);
l->packetSent();
}
pthread_mutex_unlock(&listenerLock);
}
}
void ReliableSocket::retransmitSegment(Segment segment)
{
int rc;
if (_profile->maxRetrans() > 0)
segment.setRetxCounter(segment.getRetxCounter()+1);
if ( _profile->maxRetrans() != 0 && segment.getRetxCounter() > _profile->maxRetrans()){
connectionFailure();
return;
}
sendSegment(&segment);
if (typeid(segment) == typeid(DATSegment))
{
rc = pthread_mutex_lock(&listenerLock);
list::iterator it = _listeners.begin();
while(it != _listeners.end())
{
ReliableSocketListener *l = *(++it);
l->packetRetransmitted();
}
rc = pthread_mutex_unlock(&listenerLock);
}
}
void ReliableSocket::connectionOpened()
{
int rc,cc;
if (isConnected())
{
_nullSegmentTimer->cancel();
if (_keepAlive)
_keepAliveTimer->cancel();
rc = pthread_mutex_lock(&_resetLock);
_reset = false;
pthread_cond_signal(&cond);
rc = pthread_mutex_unlock(&_resetLock);
}else
{
_in = new ReliableSocketInputStream(this);
_out = new ReliableSocketOutputStream(this);
_connected = true;
_state = ESTABLISHED;
pthread_cond_signal(&cond);
rc = pthread_mutex_lock(&stateLock);
list::iterator it = _stateListeners.begin();
while(it != _stateListeners.end())
{
ReliableSocketStateListener *l = *(++it);
l->connectionOpened(this);
}
rc = pthread_mutex_unlock(&stateLock);
}
_nullSegmentTimer->schedule(0,_profile->nullSegmentTimeout());
if (_keepAlive)
_keepAliveTimer->schedule(_profile->nullSegmentTimeout()*6,
_profile->nullSegmentTimeout()*6);
}
void ReliableSocket::connectionRefused()
{
int rc;
rc = pthread_mutex_lock(&stateLock);
list::iterator it = _stateListeners.begin();
while(it != _stateListeners.end())
{
ReliableSocketStateListener *l = *(++it);
l->connectionRefused(this);
}
rc = pthread_mutex_unlock(&stateLock);
}
void ReliableSocket::connectionClosed()
{
int rc;
rc = pthread_mutex_lock(&stateLock);
list::iterator it = _stateListeners.begin();
while(it != _stateListeners.end())
{
ReliableSocketStateListener *l = *(++it);
l->connectionClosed(this);
}
rc = pthread_mutex_unlock(&stateLock);
}
void ReliableSocket::connectionFailure()
{
int rc;
rc = pthread_mutex_lock(&_closeLock);
if (isClosed())
return;
switch(_state)
{
case SYN_SENT:
pthread_cond_signal(&cond);
break;
case CLOSE_WAIT:
case SYN_RCVD:
case ESTABLISHED:
_connected = false;
pthread_mutex_lock(&unackedSentQueue);
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&unackedSentQueue);
pthread_mutex_lock(&_recvQueueLock);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&_recvQueueLock);
closeImpl();
break;
}
_state = CLOSED;
_closed = true;
pthread_mutex_lock(&stateLock);
list::iterator it = _stateListeners.begin();
while(it != _stateListeners.end())
{
ReliableSocketStateListener *l = *(++it);
l->connectionFailure(this);
}
pthread_mutex_unlock(&stateLock);
rc = pthread_mutex_unlock(&_closeLock);
}
void ReliableSocket::connectionReset()
{
int rc;
rc = pthread_mutex_lock(&stateLock);
list::iterator it = _stateListeners.begin();
while(it != _stateListeners.end())
{
ReliableSocketStateListener *l = *(++it);
l->connectionReset(this);
}
rc = pthread_mutex_unlock(&stateLock);
}
void ReliableSocket::handleSYNSegment(SYNSegment *segment)
{
switch(_state)
{
case CLOSED:
{
_counters->setLastInSequence(segment->seq());
_state = SYN_RCVD;
srand((unsigned)time(NULL));
_profile = new ReliableSocketProfile(32, 32, segment->getMaxSegmentSize(),segment->getMaxOutstandingSegments(), segment->getMaxRetransmissions(), segment->getMaxCumulativeAcks(), segment->getMaxOutOfSequence(), segment->getMaxAutoReset(), segment->getNulSegmentTimeout(), segment->getRetransmissionTimeout(), segment->getCumulativeAckTimeout());
Segment *syn=new SYNSegment(_counters->setSequenceNumber(rand()%MAX_SEQUENCE_NUMBER),_profile->maxOutstandingSegs(),
_profile->maxSegmentSize(),
_profile->retransmissionTimeout(),
_profile->cumulativeAckTimeout(),
_profile->nullSegmentTimeout(),
_profile->maxRetrans(),
_profile->maxCumulativeAcks(),
_profile->maxOutOfSequence(),
_profile->maxAutoReset());
syn->setAck(segment->seq());
sendAndQueueSegment(syn);
break;
}
case SYN_SENT:
{
_counters->setLastInSequence(segment->seq());
_state = ESTABLISHED;
sendAck();
connectionOpened();
break;
}
}
}
void ReliableSocket::handleEAKSegment(EAKSegment *segment)
{
int rc;
list::iterator it;
int *acks = segment->getACKs();
int lastInSequence = segment->getAck();
int lastOutSequence = acks[sizeof(acks)/sizeof(int)-1];
rc = pthread_mutex_lock(&unackedSentQueue);
for(it = _unackedSentQueue.begin(); it != _unackedSentQueue.end(); )
{
Segment s=(Segment)*(++it);
if ((compareSequenceNumbers(s.seq(),lastInSequence) <= 0))
{
_unackedSentQueue.erase(it);
continue;
}
for (int i=0; i!=sizeof(acks)/sizeof(int); ++i)
{
if((compareSequenceNumbers(s.seq(),acks[i]) == 0))
{
it = _unackedSentQueue.erase(it);
break;
}
}
}
it = _unackedSentQueue.begin();
while(it != _unackedSentQueue.end())
{
Segment s = (Segment)*(++it);
if ((compareSequenceNumbers(lastInSequence,s.seq()) < 0) &&
(compareSequenceNumbers(lastOutSequence,s.seq()) > 0))
{
retransmitSegment(s);
}
}
pthread_cond_broadcast(&cond);
rc = pthread_mutex_unlock(&unackedSentQueue);
}
void ReliableSocket::handleSegment(Segment segment)
{
int rc;
if (typeid(segment) == typeid(RSTSegment))
{
rc = pthread_mutex_lock(&_resetLock);
_reset=true;
rc = pthread_mutex_unlock(&_resetLock);
connectionReset();
}
if (typeid(segment) == typeid(FINSegment))
{
switch (_state)
{
case SYN_SENT:
pthread_cond_signal(&cond);
break;
case CLOSED:
break;
default:
_state = CLOSE_WAIT;
}
}
bool inSequence = false;
rc = pthread_mutex_lock(&_recvQueueLock);
if (compareSequenceNumbers(segment.seq(),_counters->getLastInSequence()) <= 0)
{
/*drop packet: duplicate*/
}
else if (compareSequenceNumbers(segment.seq(),nextSequenceNumber(_counters->getLastInSequence())) == 0)
{
inSequence = true;
if ((_inSeqRecvQueue.size() == 0) || (_inSeqRecvQueue.size() + _outSeqRecvQueue.size() < 32))
{
_counters->setLastInSequence(segment.seq());
if (typeid(segment) == typeid(DATSegment) || typeid(segment) == typeid(RSTSegment) || typeid(segment) == typeid(FINSegment))
{
_inSeqRecvQueue.push_back(segment);
}
if (typeid(segment) == typeid(DATSegment))
{
pthread_mutex_lock(&listenerLock);
list::iterator it = _listeners.begin();
while(it != _listeners.end())
{
ReliableSocketListener *l=*(++it);
l->packetReceivedInOrder();
}
pthread_mutex_unlock(&listenerLock);
}
checkRecvQueues();
}else
{/*Drop packet: queue is full*/}
}
else if (_inSeqRecvQueue.size()+_outSeqRecvQueue.size() < 32)
{
bool added= false;
for(list::iterator it = _outSeqRecvQueue.begin();it != _outSeqRecvQueue.end() && !added;++it)
{
Segment s= (Segment)*it;
int cmp = compareSequenceNumbers(segment.seq(),s.seq());
if (cmp = 0)
{
added = true;
}
else if(cmp<0)
{
_outSeqRecvQueue.insert(it,segment);
added = true;
}
}
if (!added)
_outSeqRecvQueue.push_back(segment);
_counters->incOutOfSequenceCounter();
if (typeid(segment) == typeid(DATSegment))
{
pthread_mutex_lock(&listenerLock);
list::iterator it = _listeners.begin();
while (it != _listeners.end())
{
ReliableSocketListener *l = *(++it);
l->packetReceivedOutOrder();
}
pthread_mutex_unlock(&listenerLock);
}
}
if (inSequence && (typeid(segment) == typeid(RSTSegment) || typeid(segment) == typeid(NULSegment) || typeid(segment) == typeid(FINSegment)))
{
sendAck();
}
else if ((_counters->getOutOfSequenceCounter()>0) && _profile->maxOutOfSequence() == 0 || _counters->getOutOfSequenceCounter() > _profile->maxOutOfSequence())
{
sendExtendedAck();
}
else if ((_counters->getCumulativeAckCounter() >0) && (_profile->maxCumulativeAcks() == 0 ||_counters->getCumulativeAckCounter() > _profile->maxCumulativeAcks()))
{
sendSingleAck();
}
else
{
if (_cumulativeAckTimer->isIdle())
_cumulativeAckTimer->schedule(_profile->cumulativeAckTimeout());
}
rc = pthread_mutex_unlock(&_recvQueueLock);
}
void ReliableSocket::sendAck()
{
int rc;
rc=pthread_mutex_lock(&_recvQueueLock);
if (!_outSeqRecvQueue.empty())
{
sendExtendedAck();
return;
}
sendSingleAck();
rc=pthread_mutex_unlock(&_recvQueueLock);
}
void ReliableSocket::sendExtendedAck()
{
int rc;
rc=pthread_mutex_lock(&_recvQueueLock);
if (_outSeqRecvQueue.empty())
return;
_counters->getAndResetCumulativeAckCounter();
_counters->getAndResetOutOfSequenceCounter();
/*Compose list of out-of-sequence sequence numbers*/
int *acks = new int[_outSeqRecvQueue.size()];
list::iterator it;
int i;
for (i = 0,it = _outSeqRecvQueue.begin(); it != _outSeqRecvQueue.end(); ++i,++it)
{
Segment s = *it;
acks[i] = s.seq();
}
int lastInSequence = _counters->getLastInSequence();
sendSegment(new EAKSegment(nextSequenceNumber(lastInSequence),lastInSequence,acks));
rc=pthread_mutex_unlock(&_recvQueueLock);
}
void ReliableSocket::sendSingleAck()
{
if (_counters->getAndResetCumulativeAckCounter() == 0)
return;
int lastInSequence = _counters->getLastInSequence();
sendSegment(new ACKSegment(nextSequenceNumber(lastInSequence),lastInSequence));
}
void ReliableSocket::checkAndSetAck(Segment s)
{
if (_counters->getAndResetCumulativeAckCounter() == 0)
return;
s.setAck(_counters->getLastInSequence());
}
void ReliableSocket::checkAndGetAck(Segment segment)
{
int rc;
int ackn = segment.getAck();
if (ackn < 0)
return;
_counters->getAndResetOutstandingSegsCounter();
if (_state == SYN_RCVD)
{
_state = ESTABLISHED;
connectionOpened();
}
rc = pthread_mutex_lock(&unackedSentQueue);
list::iterator it = _unackedSentQueue.begin();
while(it != _unackedSentQueue.end())
{
Segment s = (Segment)*it;
if (compareSequenceNumbers(s.seq(),ackn) <= 0)
_unackedSentQueue.erase(it);
}
if (_unackedSentQueue.empty())
_retransmissionTimer->cancel();
pthread_cond_broadcast(&cond);
rc = pthread_mutex_lock(&unackedSentQueue);
}
void ReliableSocket::checkRecvQueues()
{
int rc;
rc = pthread_mutex_lock(&_recvQueueLock);
list::iterator it = _outSeqRecvQueue.begin();
while(it != _outSeqRecvQueue.end())
{
Segment s = (Segment)(*it);
if (compareSequenceNumbers(s.seq(),nextSequenceNumber(_counters->getLastInSequence())) == 0)
{
_counters->setLastInSequence(s.seq());
if (typeid(s) == typeid(DATSegment) || typeid(s) == typeid(RSTSegment) || typeid(s) == typeid(FINSegment))
_inSeqRecvQueue.push_back(s);
_outSeqRecvQueue.erase(it);
}
}
pthread_cond_signal(&cond);
rc = pthread_mutex_unlock(&_recvQueueLock);
}
void ReliableSocket::sendSegmentImpl(Segment *s)
{
int snd;
snd = sendto(_sock, s->getBytes(), s->length(), 0, _endpoint, sizeof(struct sockaddr));
}
Segment* ReliableSocket::receiveSegmentImpl()
{
Segment s;
int rcv;
_recvbuffer = new unsigned char[65535];
rcv = recv(_sock, _recvbuffer, sizeof(_recvbuffer),0);
return s.parse(_recvbuffer, 0, sizeof(_recvbuffer));
}
void ReliableSocket::closeSocket()
{
close(_sock);
}
void ReliableSocket::closeImpl()
{
_nullSegmentTimer->destroy();
_keepAliveTimer->destroy();
_state = CLOSE_WAIT;
}
int ReliableSocket::compareSequenceNumbers(int seqn, int aseqn)
{
if (seqn == aseqn)
return 0;
else if (((seqn MAX_SEQUENCE_NUMBER/2)) ||
((seqn>aseqn) && ((seqn-aseqn) < MAX_SEQUENCE_NUMBER/2)))
return 1;
else
return -1;
}
/*
int Counters::nextSequenceNumber(int seqn)
{
return (seqn+1)%MAX_SEQUENCE_NUMBER;
} */
//Counters类
int Counters::nextSequenceNumber()
{
return (_seqn = ReliableSocket::nextSequenceNumber(_seqn));
}
int Counters::setSequenceNumber(int n)
{
_seqn = n;
return _seqn;
}
int Counters::setLastInSequence(int n)
{
_lastInSequence = n;
return _lastInSequence;
}
int Counters::getLastInSequence()
{
return _lastInSequence;
}
int Counters::getCumulativeAckCounter()
{
return _cumAckCounter;
}
int Counters::getAndResetCumulativeAckCounter()
{
int tmp = _cumAckCounter;
_cumAckCounter = 0;
return tmp;
}
int Counters::getOutOfSequenceCounter()
{
return _outOfSeqCounter;
}
int Counters::getAndResetOutOfSequenceCounter()
{
int tmp = _outOfSeqCounter;
_outOfSeqCounter = 0;
return tmp;
}
int Counters::getOutstandingSegsCounter()
{
return _outSegsCounter;
}
int Counters::getAndResetOutstandingSegsCounter()
{
int tmp = _outSegsCounter;
_outSegsCounter = 0;
return tmp;
}
void Counters::incCumulativeAckCounter()
{
_cumAckCounter++;
}
void Counters::incOutOfSequenceCounter()
{
_outOfSeqCounter++;
}
void Counters::incOutstandingSegsCounter()
{
_outSegsCounter++;
}
void Counters::reset()
{
_outOfSeqCounter = 0;
_outSegsCounter = 0;
_cumAckCounter = 0;
}
void ReliableSocketThread::run()
{
Segment *segment;
ReliableSocket p;
while ((segment = (p.receiveSegmentImpl())) != NULL)
{
if (typeid(segment) == typeid(SYNSegment))
p.handleSYNSegment((SYNSegment*)segment);
else if (typeid(segment) == typeid(EAKSegment))
p.handleEAKSegment((EAKSegment*)segment);
else if (typeid(segment) == typeid(ACKSegment))
{}//do nothing
else
p.handleSegment(*segment);
p.checkAndGetAck(*segment);
}
}
//class NullSegmentTimerTask "ReliableSocket.h" LINE 244.
void NullSegmentTimerTask::run()
{
ReliableSocket p;
if(p._unackedSentQueue.empty())
p.sendAndQueueSegment(new NULSegment(p._counters->nextSequenceNumber()));
}
void RetransmissionTimerTask::run()
{
ReliableSocket p;
list::iterator it = p._unackedSentQueue.begin();
while(it != p._unackedSentQueue.end())
{
Segment s = (Segment)*(++it);
p.retransmitSegment(s);
}
}
void CumulativeAckTimerTask::run()
{
ReliableSocket p;
p.sendAck();
}
void KeepAliveTimerTask::run()
{
ReliableSocket p;
p.connectionFailure();
}
void ShutdownHook::run()
{
ReliableSocket p;
switch(p._state)
{
case ReliableSocket::CLOSED:
return;
default:
p.sendSegment(new FINSegment(p._counters->nextSequenceNumber()));
break;
}
}
//ReliableSocketInputStream类
ReliableSocketInputStream::ReliableSocketInputStream(ReliableSocket *sock)
{
if(sock==NULL)
cout<<"sock"<getReceiveBufferSize()];
_pos=_count=0;
}
int ReliableSocketInputStream::read()
{
int rc;
rc=pthread_mutex_lock(&mutex);
if(ReliableSocketInputStream::readImpl()<0)
{
return -1;
}
rc=pthread_mutex_unlock(&mutex);
return _buf[_pos++]&0xFF;
}
int ReliableSocketInputStream::read(unsigned char b[])
{
int rc;
return ReliableSocketInputStream::read(b,0,sizeof(b));
}
int ReliableSocketInputStream::read(unsigned char b[],int off,int len)
{
int rc;
rc=pthread_mutex_lock(&mutex);
if(ReliableSocketInputStream::readImpl()<0)
return -1;
int readBytes;
if(ReliableSocketInputStream::available()read(_buf,0,sizeof(_buf));
}
return _count;
}
//常量初始化.
const int ReliableServerSocket::DEFAULT_BACKLOG_SIZE = 50;
ReliableServerSocket::ReliableServerSocket(struct in_addr *Inetaddr,int port,int backlog){
int sfd;
sfd=socket(AF_INET,SOCK_DGRAM,0);
ReliableServerSocket(sfd,backlog);
}
ReliableServerSocket::ReliableServerSocket(int sockfd,int backlog)
{
sockfd=socket(AF_INET,SOCK_DGRAM,0);
_serverSock = sockfd;
_backlogSize = (backlog<=0)?DEFAULT_BACKLOG_SIZE:backlog;
_backlog = new list(_backlogSize);
_timeout = 0;
_closed = false;
thread->start(); //ReceiveThread.
}
ReliableSocket ReliableServerSocket::accept(){
if(isClosed())
cout<<"Socket is closed"<empty()){
try{
if(_timeout == 0)
{
pthread_cond_wait(&cond,&_backLock);
}
else
{
int64 startTime = LogTimeMM::getSystemTime();
pthread_cond_wait(&cond,&_backLock);
if(LogTimeMM::getSystemTime()-startTime >= _timeout)
cout<<"timeout!"<begin());
_backlog->pop_front();
return sock;
}
void ReliableServerSocket::bindSock(struct sockaddr_in *my_addr, int backlog)
{
int dgram;
if(isClosed())
cout<<"Socket is closed!"<sin_port = 0; //系统随机选择一个未被使用的端口号
my_addr->sin_addr.s_addr = INADDR_ANY; //返回本机链接的地址
isbind = bind(dgram,(struct sockaddr *)my_addr,sizeof(my_addr));
}
void ReliableServerSocket::closeServSock()
{
if(isClosed())
{
return;
}
_closed = true;
pthread_mutex_lock(&_backLock);
_backlog->clear();
pthread_cond_signal(&cond);
pthread_mutex_unlock(&_backLock);
if(_clientSockTable.empty())
{
close(_serverSock);
}
}
/*void ReliableServerSocket::setSoTimeout(int timeout)
{
if(timeout<0)
cout<<"timeout<0"<::iterator iter = _clientSockTable.find(my_addr);
ReliableClientSocket *sock = (ReliableClientSocket*)(iter->second);
if(sock==NULL)
{
sock=new ReliableClientSocket(_serverSock,(struct sockaddr_in*)&my_addr);
sock->addStateListener(_stateListener);
_clientSockTable.insert(make_pair(my_addr,sock));
delete sock;
}
lck = pthread_mutex_unlock(&_clientSockLock);
return sock;
*/
}
ReliableClientSocket* ReliableServerSocket::removeClientSocket(struct sockaddr_in my_addr)
{
/* int lck;
lck = pthread_mutex_lock(&_clientSockLock);
hash_map::iterator iter;
iter=_clientSockTable.find(my_addr);
ReliableClientSocket *sock = (ReliableClientSocket*)(iter->second);
_clientSockTable.erase(my_addr);
if(_clientSockTable.empty())
{
if(isClosed()){close(_serverSock);}
}
lck = pthread_mutex_lock(&_clientSockLock);
return sock;
*/
}
//ReceiverThread类
void ReceiverThread::run()
{
/* ReliableServerSocket p;
Segment seg;
unsigned char *buffer=new unsigned char[65535];
while(true)
{
DatagramPacket *packet = new DatagramPacket(buffer, sizeof(buffer));
ReliableClientSocket *sock;
try{
int rv=recv(p._serverSock,buffer,sizeof(buffer),0);
struct sockaddr_in endpoint = packet->getSocketAddress();
Segment *s=seg.parse(packet->getData(),0,packet->getLength());
if(!p.isClosed())
{
if(typeid(s) == typeid(SYNSegment))
{
if(p._clientSockTable.find(endpoint) == p._clientSockTable.end())
sock = p.addClientSocket(endpoint);
}
}
hash_map::iterator it;
it = p._clientSockTable.find(endpoint);
if (it != p._clientSockTable.end())
sock = it->second;
if (sock != NULL)
sock->segmentReceived(s);
}
catch(...)
{
if (p.isClosed())
break;
cout<<"exception!"<;
p->init(sockfd,profile);
}
Segment* ReliableClientSocket::receiveSegmentImpl()
{
pthread_mutex_lock(&_queueLock);
while(_queue->empty()){
pthread_cond_wait(&childCond,&_queueLock);
}
Segment *s = (Segment*)*(_queue->begin());
_queue->pop_front();
pthread_mutex_unlock(&_queueLock);
return s;
}
void ReliableClientSocket::segmentReceived(Segment *s)
{
pthread_mutex_lock(&_queueLock);
_queue->push_back(s);
pthread_cond_signal(&childCond);
pthread_mutex_unlock(&_queueLock);
}
void ReliableClientSocket::closeSocket()
{
pthread_mutex_lock(&_queueLock);
_queue->clear();
pthread_cond_signal(&childCond);
pthread_mutex_unlock(&_queueLock);
}
//class StateListener
/*
void StateListener::connectionOpened(ReliableSocket *sock)
{
int lck;
if (typeid(*sock) == typeid(ReliableClientSocket))
{
lck =pthread_mutex_lock(&ReliableSocket::_backLock);
while (_backlog.size() > DEFAULT_BACKLOG_SIZE)
{
pthread_cond_wait(&ReliableSocket::cond, &ReliableSocket::_backLock);
}
_backlog.push_back(*sock);
pthread_cond_signal(&ReliableSocket::cond);
lck =pthread_mutex_unlock(&ReliableSocket::_backLock);
}
}
void StateListener::connectionRefused(ReliableSocket *sock)
{}
void StateListener::connectionClosed(ReliableSocket *sock)
{}
void StateListener::connectionFailure(ReliableSocket *sock)
{}
void StateListener::connectionReset(ReliableSocket *sock)
{}
*/
#ifndef DATAGRAMPACKET_H
#define DATAGRAMPACKET_H
#include
#include
#include
#include
using namespace std;
class DatagramPacket
{
public:
typedef unsigned char byte;
DatagramPacket(byte _buf[], int _length, int _offset = 0);
DatagramPacket(byte _buf[], int _length, struct in_addr _address, int port, int _offset = 0);
struct in_addr getAddress() {return *address;}
int getPort() {return port;}
byte* getData() {return buf;}
int getOffset() {return offset;}
int getLength() {return length;}
void setData(byte _buf[],int offset, int length);
void setData(byte _buf[]);
void setAddress(struct in_addr iaddr);
void setPort(int iPort);
void setLength(int _length);
struct sockaddr_in getSocketAddress();
private:
byte *buf;
int offset;
int length;
int bufLength;
int port;
struct in_addr *address;
struct sockaddr_in InAddr;
};
#endif
#include "DatagramPacket.h"
/* * * * * * * * * * * * * * * * */
/* 类的实现 */
/* * * * * * * * * * * * * * * * */
DatagramPacket::DatagramPacket(byte _buf[], int _length, int _offset)
{
setData(buf, offset, length);
this->address = NULL;
this->port = -1;
}
DatagramPacket::DatagramPacket(byte _buf[], int _length, struct in_addr _address, int _port, int _offset)
{
setData(_buf, _offset, _length);
setAddress(_address);
setPort(_port);
}
void DatagramPacket::setData(byte _buf[],int _offset, int _length)
{
if (_length < 0 || _offset < 0 || (_length + _offset) < 0 ||
((_length + _offset) > sizeof(buf)))
cout<<"illegal length or offset!"<buf = _buf;
this->length = _length;
this->bufLength = _length;
this->offset = _offset;
}
void DatagramPacket::setData(byte _buf[])
{
if (_buf == NULL)
cout<<"null packet buffer"<buf = _buf;
this->offset = 0;
this->length = sizeof(_buf)/sizeof(byte);
this->bufLength = sizeof(_buf)/sizeof(byte);
}
void DatagramPacket::setAddress(struct in_addr iaddr)
{
address = &iaddr;
}
void DatagramPacket::setPort(int iPort)
{
if (iPort < 0 || iPort > 0xFFF)
cout<<"Port out of range: "< sizeof(buf) || _length < 0 || (_length+offset)< 0)
cout<<"illegal length!"<length = _length;
this->bufLength = this->length;
}
#pragma once
class ReliableSocketListener
{
public:
//Invoked when a data packet is sent.
virtual void packetSent();
//Invoked when a data packet is retransmitted.
virtual void packetRetransmitted();
//Invoked when a data packet is received in-order.
virtual void packetReceivedInOrder();
//Invoked when a out of sequence data packet is received.
virtual void packetReceivedOutOrder();
};
#ifndef _RELIABLESOCKETOUTPUTSTREAM_H_
#define _RELIABLESOCKETOUTPUTSTREAM_H_
#include "ReliableSocket.h"
/*类的前向声明*/
class ReliableSocket;
class ReliableSocketOutputStream:public ostream
{
public:
ReliableSocketOutputStream(ReliableSocket *sock);
void write(int b);
void write(unsigned char b[]);
void write(unsigned char b[],int off,int len);
void flush();
void close();
protected:
ReliableSocket *_sock;
unsigned char *_buf;
int _count;
private:
pthread_mutex_t mutex;
};
#endif
#include "ReliableSocketOutputStream.h"
using namespace std;
ReliableSocketOutputStream::ReliableSocketOutputStream(ReliableSocket *sock)
{
if(sock==NULL)
{
cout<<"sock"<getSendBufferSize()];
_count=0;
}
void ReliableSocketOutputStream::write(int b)
{
int rc;
rc=pthread_mutex_lock(&mutex);
if(_count>=sizeof(_buf))
ReliableSocketOutputStream::flush();
_buf[_count++]=(unsigned char)(b&0xFF);
rc=pthread_mutex_unlock(&mutex);
}
void ReliableSocketOutputStream::write(unsigned char b[])
{
int rc;
rc=pthread_mutex_lock(&mutex);
write(b,0,sizeof(b));
rc=pthread_mutex_unlock(&mutex);
}
void ReliableSocketOutputStream::write(unsigned char b[], int off, int len)
{
int rc;
rc=pthread_mutex_lock(&mutex);
int buflen;
int writtenBytes=0;
while(writtenByteslen-writtenBytes)
buflen=len-writtenBytes;
else
buflen=sizeof(_buf);
if(buflen>sizeof(_buf)-_count)
flush();
for(size_t bindex=off+writtenBytes,_index=_count;_index!=_count+buflen;++bindex,++_index)
_buf[_index]=b[bindex];
_count+=buflen;
writtenBytes+=buflen;
}
rc=pthread_mutex_unlock(&mutex);
}
void ReliableSocketOutputStream::flush()
{
int rc;
rc=pthread_mutex_lock(&mutex);
if(_count>0){
write(_buf,0,_count);
_count=0;
}
rc=pthread_mutex_unlock(&mutex);
}
void ReliableSocketOutputStream::close()
{
int rc;
rc=pthread_mutex_lock(&mutex);
this->flush();
_sock->shutdownOutput();
rc=pthread_mutex_unlock(&mutex);
}
#pragma once
#include
class ReliableSocketProfile
{
public:
static const int MAX_SEND_QUEUE_SIZE;
static const int MAX_RECV_QUEUE_SIZE;
static const int MAX_SEGMENT_SIZE;
static const int MAX_OUTSTANDING_SEGS;
static const int MAX_RETRANS;
static const int MAX_CUMULATIVE_ACKS;
static const int MAX_OUT_OF_SEQUENCE;
static const int MAX_AUTO_RESET;
static const int NULL_SEGMENT_TIMEOUT;
static const int RETRANSMISSION_TIMEOUT;
static const int CUMULATIVE_ACK_TIMEOUT;
int maxSendQueueSize(){return _maxSendQueueSize;}
int maxRecvQueueSize(){return _maxRecvQueueSize;}
int maxSegmentSize(){return _maxSegmentSize;}
int maxOutstandingSegs(){return _maxOutstandingSegs;}
int maxRetrans(){return _maxRetrans;}
int maxCumulativeAcks(){return _maxCumulativeAcks;}
int maxOutOfSequence(){return _maxOutOfSequence;}
int maxAutoReset(){return _maxAutoReset;}
int nullSegmentTimeout(){return _nullSegmentTimeout;}
int retransmissionTimeout(){return _retransmissionTimeout;}
int cumulativeAckTimeout(){return _cumulativeAckTimeout;}
ReliableSocketProfile();
ReliableSocketProfile(int maxSendQueueSize,int maxRecvQueueSize,int maxSegmentSize,int maxOutstandingSegs,int maxRetrans,
int maxCumulativeAcks,int maxOutOfSequence,int maxAutoReset,int nullSegmentTimeout,int retransmissionTimeout,int cumulativeTimeout);
std::string toString();
private:
void checkValue(const std::string param,int value,int minValue,int maxValue);
int _maxSendQueueSize;
int _maxRecvQueueSize;
int _maxSegmentSize;
int _maxOutstandingSegs;
int _maxRetrans;
int _maxCumulativeAcks;
int _maxOutOfSequence;
int _maxAutoReset;
int _nullSegmentTimeout;
int _retransmissionTimeout;
int _cumulativeAckTimeout;
};
#include "ReliableSocketProfile.h"
#include
using namespace std;
const int ReliableSocketProfile::MAX_SEND_QUEUE_SIZE = 32;
const int ReliableSocketProfile::MAX_RECV_QUEUE_SIZE = 32;
const int ReliableSocketProfile::MAX_SEGMENT_SIZE = 128;
const int ReliableSocketProfile::MAX_OUTSTANDING_SEGS = 3;
const int ReliableSocketProfile::MAX_RETRANS = 3;
const int ReliableSocketProfile::MAX_CUMULATIVE_ACKS = 3;
const int ReliableSocketProfile::MAX_OUT_OF_SEQUENCE = 3;
const int ReliableSocketProfile::MAX_AUTO_RESET = 3;
const int ReliableSocketProfile::NULL_SEGMENT_TIMEOUT = 2000;
const int ReliableSocketProfile::RETRANSMISSION_TIMEOUT= 600;
const int ReliableSocketProfile::CUMULATIVE_ACK_TIMEOUT= 300;
ReliableSocketProfile::ReliableSocketProfile(){
ReliableSocketProfile(MAX_SEND_QUEUE_SIZE,MAX_RECV_QUEUE_SIZE,MAX_SEGMENT_SIZE,MAX_OUTSTANDING_SEGS,0,MAX_CUMULATIVE_ACKS,MAX_OUT_OF_SEQUENCE,MAX_AUTO_RESET,NULL_SEGMENT_TIMEOUT,RETRANSMISSION_TIMEOUT,CUMULATIVE_ACK_TIMEOUT);
}
ReliableSocketProfile::ReliableSocketProfile(int maxSendQueueSize,int maxRecvQueueSize,int maxSegmentSize,int maxOutstandingSegs, int maxRetrans,
int maxCumulativeAcks,int maxOutOfSequence,int maxAutoReset,int nullSegmentTimeout,int retransmissionTimeout,int cumulativeAckTimeout)
{
checkValue("maxSendQueueSize", maxSendQueueSize, 1, 255);
checkValue("maxRecvQueueSize", maxRecvQueueSize, 1, 255);
checkValue("maxSegmentSize", maxSegmentSize, 22, 65535);
checkValue("maxOutstandingSegs", maxOutstandingSegs, 1, 255);
checkValue("maxRetrans", maxRetrans, 0, 255);
checkValue("maxCumulativeAcks", maxCumulativeAcks, 0, 255);
checkValue("maxOutOfSequence", maxOutOfSequence, 0, 255);
checkValue("maxAutoReset", maxAutoReset, 0, 255);
checkValue("nullSegmentTimeout", nullSegmentTimeout, 0, 65535);
checkValue("retransmissionTimeout",retransmissionTimeout,100,65535);
checkValue("cumulativeAckTimeout", cumulativeAckTimeout, 100,65535);
_maxSendQueueSize = maxSendQueueSize;
_maxRecvQueueSize = maxRecvQueueSize;
_maxSegmentSize = maxSegmentSize;
_maxOutstandingSegs = maxOutstandingSegs;
_maxRetrans = maxRetrans;
_maxCumulativeAcks = maxCumulativeAcks;
_maxOutOfSequence = maxOutOfSequence;
_maxAutoReset = maxAutoReset;
_nullSegmentTimeout = nullSegmentTimeout;
_retransmissionTimeout = retransmissionTimeout;
_cumulativeAckTimeout = cumulativeAckTimeout;
}
string ReliableSocketProfile::toString()
{
string sb="[";
sb+=(_maxSendQueueSize+'0');
sb+=",";
sb+=(_maxRecvQueueSize+'0');
sb+=",";
sb+=(_maxSegmentSize+'0');
sb+=",";
sb+=(_maxOutstandingSegs+'0');
sb+=",";
sb+=(_maxRetrans+'0');
sb+=",";
sb+=(_maxCumulativeAcks+'0');
sb+=",";
sb+=(_maxOutOfSequence+'0');
sb+=",";
sb+=(_maxAutoReset+'0');
sb+=",";
sb+=(_nullSegmentTimeout+'0');
sb+=",";
sb+=(_retransmissionTimeout+'0');
sb+=",";
sb+=(_cumulativeAckTimeout='0');
sb+="]";
return sb;
}
void ReliableSocketProfile::checkValue(const string param,int value,int minValue,int maxValue)
{
if(valuemaxValue)
throw new invalid_argument(param);
}
#pragma once
#include "ReliableSocket.h"
class ReliableSocket;
class ReliableSocketStateListener
{
public:
virtual void connectionOpened(ReliableSocket *sock);
virtual void connectionRefused(ReliableSocket *sock);
virtual void connectionClosed(ReliableSocket *sock);
virtual void connectionFailure(ReliableSocket *sock);
virtual void connectionReset(ReliableSocket *sock);
};
#ifndef SEGMENT_H
#define SEGMENT_H
#include
#include
#include
#include
class Segment{
public:
static const int RUDP_VERSION;
static const int RUDP_HEADER_LEN;
static const unsigned char SYN_FLAG;
static const unsigned char ACK_FLAG;
static const unsigned char EAK_FLAG;
static const unsigned char RST_FLAG;
static const unsigned char NUL_FLAG;
static const unsigned char CHK_FLAG;
static const unsigned char FIN_FLAG;
Segment():_nretx(0),_ackn(-1){}
Segment* parse(unsigned char bytes[]);
Segment* parse(unsigned char bytes[],int off,int len);
unsigned char* getBytes();
int flags() {return _flags;}
int seq() {return _seqn;}
int length(){return _hlen;}
int getRetxCounter() {return _nretx;}
void setRetxCounter(int n) {_nretx=n;}
int getAck();
void setAck(int ackn);
virtual std::string type();
private:
int _flags;
int _hlen;
int _seqn;
int _ackn;
int _nretx;
protected:
void init(int flags,int seqn,int len){_flags=flags;_seqn=seqn;_hlen=len;}
void parseBytes(unsigned char bytes[],int off,int len);
};
/*SYNSegment class*/
class SYNSegment:public Segment
{
public:
SYNSegment(){}
SYNSegment(int seqn, int maxseg, int maxsegsize, int rettoval,
int cumacktoval, int niltoval, int maxret,
int maxcumack, int maxoutseq, int maxautorst);
int getVersion() {return _version;}
int getMaxOutstandingSegments() { return _maxseg;}
int getOptionFlags() { return _optflags;}
int getMaxSegmentSize() { return _maxsegsize;}
int getRetransmissionTimeout() { return _rettoval;}
int getCumulativeAckTimeout() { return _cumacktoval;}
int getNulSegmentTimeout() { return _niltoval;}
int getMaxRetransmissions() { return _maxret;}
int getMaxCumulativeAcks() { return _maxcumack;}
int getMaxOutOfSequence() {return _maxoutseq;}
int getMaxAutoReset() { return _maxautorst;}
unsigned char* getBytes();
protected:
void parseBytes(unsigned char buffer[], int off, int len);
private:
int _version;
int _maxseg;
int _optflags;
int _maxsegsize;
int _rettoval;
int _cumacktoval;
int _niltoval;
int _maxret;
int _maxcumack;
int _maxoutseq;
int _maxautorst;
static const int SYN_HEADER_LEN ;//6+16
};
/*NULSegment*/
class NULSegment:public Segment
{
public:
NULSegment(){}
NULSegment(int seqn);
std::string type(){return "NUL";}
};
/*ACKSegment class*/
class ACKSegment:public Segment
{
public:
ACKSegment(){}
ACKSegment(int seqn,int ackn);
std::string type(){return "ACK";}
};
/*EAKSegment class*/
class EAKSegment:public ACKSegment
{
public:
EAKSegment(){}
EAKSegment(int seqn,int ackn,int acks[]);
std::string type(){return "EAK";}
int* getACKs(){return _acks;}
unsigned char* getBytes();
protected:
void parseBytes(unsigned char buffer[],int off,int len);
private:
int *_acks;
};
/*RSTSegment class*/
class RSTSegment:public Segment
{
public:
RSTSegment(){};
RSTSegment(int seqn);
std::string type(){return "RST";}
};
/*FINSegment class*/
class FINSegment:public Segment
{
public:
FINSegment(){};
FINSegment(int seqn);
std::string type(){return "FIN";}
};
/*DATSegment class*/
class DATSegment:public Segment{
public:
DATSegment(){}
DATSegment(int seqn,int ackn,unsigned char b[],int off,int len);
int length(){return sizeof(_data)+Segment::length();}
unsigned char* getBytes();
void parseBytes(unsigned char buffer[],int off, int len);
unsigned char* getData(){return _data;}
private:
unsigned char *_data;
};
#endif
#include "Segment.h"
using namespace std;
/* * * * * * * * * * * */
/* 类的实现部分! */
/* * * * * * * * * * * */
const int Segment::RUDP_VERSION=1;
const int Segment::RUDP_HEADER_LEN=6;
const unsigned char Segment::SYN_FLAG=(unsigned char)0x80;
const unsigned char Segment::ACK_FLAG=(unsigned char)0x40;
const unsigned char Segment::EAK_FLAG=(unsigned char)0x20;
const unsigned char Segment::RST_FLAG=(unsigned char)0x10;
const unsigned char Segment::NUL_FLAG=(unsigned char)0x08;
const unsigned char Segment::CHK_FLAG=(unsigned char)0x04;
const unsigned char Segment::FIN_FLAG=(unsigned char)0x02;
int Segment::getAck()
{
if((_flags&Segment::ACK_FLAG)==Segment::ACK_FLAG)
return _ackn;
else
return -1;
}
void Segment::setAck(int ackn)
{
_flags=_flags|Segment::ACK_FLAG;
_ackn=ackn;
}
unsigned char* Segment::getBytes()
{
unsigned char *buffer=new unsigned char[length()];
buffer[0]=(unsigned char)(_flags&0xFF);
buffer[1]=(unsigned char)(_hlen&0xFF);
buffer[2]=(unsigned char)(_seqn&0xFF);
buffer[3]=(unsigned char)(_ackn&0xFF);
return buffer;
}
Segment* Segment::parse(unsigned char bytes[])
{
return parse(bytes,0,sizeof(bytes));
}
Segment* Segment::parse(unsigned char bytes[],int off,int len)
{
Segment *segment = NULL;
if(lenparseBytes(bytes,off,len);
return segment;
}
void Segment::parseBytes(unsigned char buffer[],int off,int len)
{
_flags =(buffer[off]&0xFF);
_hlen =(buffer[off+1]&0xFF);
_seqn =(buffer[off+2]&0xFF);
_ackn =(buffer[off+3]&0xFF);
}
/*SYNSegment class define*/
SYNSegment::SYNSegment(int seqn, int maxseg, int maxsegsize, int rettoval,
int cumacktoval, int niltoval, int maxret,
int maxcumack, int maxoutseq, int maxautorst)
{
init(SYN_FLAG, seqn, SYN_HEADER_LEN);
_version = RUDP_VERSION;
_maxseg = maxseg;
_optflags = 0x01; /* no options */
_maxsegsize = maxsegsize;
_rettoval = rettoval;
_cumacktoval = cumacktoval;
_niltoval = niltoval;
_maxret = maxret;
_maxcumack = maxcumack;
_maxoutseq = maxoutseq;
_maxautorst = maxautorst;
}
unsigned char* SYNSegment::getBytes()
{
unsigned char *buffer=Segment::getBytes();
buffer[4] = (unsigned char) ((_version << 4) & 0xFF);
buffer[5] = (unsigned char) (_maxseg & 0xFF);
buffer[6] = (unsigned char) (_optflags & 0xFF);
buffer[7] = 0; /* spare */
buffer[8] = (unsigned char) ((_maxsegsize >> 8) & 0xFF);
buffer[9] = (unsigned char) ((_maxsegsize >> 0) & 0xFF);
buffer[10] = (unsigned char) ((_rettoval >> 8) & 0xFF);
buffer[11] = (unsigned char) ((_rettoval >> 0) & 0xFF);
buffer[12] = (unsigned char) ((_cumacktoval >> 8) & 0xFF);
buffer[13] = (unsigned char) ((_cumacktoval >> 0) & 0xFF);
buffer[14] = (unsigned char) ((_niltoval >> 8) & 0xFF);
buffer[15] = (unsigned char) ((_niltoval >> 0) & 0xFF);
buffer[16] = (unsigned char) (_maxret & 0xFF);
buffer[17] = (unsigned char) (_maxcumack & 0xFF);
buffer[18] = (unsigned char) (_maxoutseq & 0xFF);
buffer[19] = (unsigned char) (_maxautorst & 0xFF);
return buffer;
}
void SYNSegment::parseBytes(unsigned char buffer[], int off, int len)
{
Segment::parseBytes(buffer, off, len);
if (len < (SYN_HEADER_LEN)) {
cout<<"Invalid SYN segment"<> 4);
if (_version != RUDP_VERSION) {
cout<<"Invalid RUDP version"<
#ifndef _THREAD_H
#define _THREAD_H
#include
#include
class Runnable
{
public:
virtual void run()=0;
};
class Thread:public Runnable
{
private:
//线程初始化序号
static int threadInitNumber;
//当前线程初始化序号
int curThreadInitNumber;
//线程体;
Runnable *target;
//当前线程的线程ID
pthread_t tid;
//线程的状态
int threadStatus;
//线程属性
pthread_attr_t attr;
//线程优先级
sched_param param;
//获取执行方法的指针
static void* run0(void* pVoid);
//内部执行方法
void* run1();
//获取一个线程序号
static int getNextThreadNum();
public:
//线程的状态-新建
static const int THREAD_STATUS_NEW = 0;
//线程的状态-正在运行
static const int THREAD_STATUS_RUNNING = 1;
//线程的状态-运行结束
static const int THREAD_STATUS_EXIT = -1;
//构造函数
Thread();
Thread(Runnable *iTarget);
//析构函数
~Thread();
//线程的运行实体
void run();
//开始执行线程
bool start();
//获取线程状态
int getState();
//等待线程直至退出
void join();
//等待线程退出或者超时
void join(unsigned long millisTime);
//比较两个线程时候相同,通过curThreadInitNumber判断
bool operator==(const Thread *otherThread);
//获取this线程ID
pthread_t getThreadID();
//获取当前ID
static pthread_t getCurrentThreadID();
//当前线程是否和模个线程相等,通过tid判断
static bool isEquals(Thread *iTarget);
//设置线程的类型:绑定/非绑定
void setThreadScope(bool isSystem);
//获取线程的类型:绑定/非绑定
bool getThreadScope();
//设置线程的优先级,1-99,其中99为实时;其他的为普通
void setThreadPriority(int priority);
//获取线程的优先级
int getThreadPriority();
};
#endif/*_THREAD_H*/
#include "Thread.h"
int Thread::threadInitNumber=1;
inline int Thread::getNextThreadNum()
{
return threadInitNumber++;
}
void* Thread::run0(void* pVoid)
{
Thread* p=(Thread*)pVoid;
p->run1();
return p;
}
void* Thread::run1()
{
threadStatus=THREAD_STATUS_RUNNING;
tid=pthread_self();
run();
threadStatus=THREAD_STATUS_EXIT;
tid=0;
pthread_exit(NULL);
}
void Thread::run()
{
if(target!=NULL)
{
(*target).run();
}
}
Thread::Thread(Runnable *iTarget)
{
target=iTarget;
tid=0;
threadStatus=THREAD_STATUS_NEW;
curThreadInitNumber=getNextThreadNum();
pthread_attr_init(&attr);
}
Thread::~Thread()
{
pthread_attr_destroy(&attr);
}
bool Thread::start()
{
return pthread_create(&tid,NULL,run0,this)==0;
}
inline pthread_t Thread::getCurrentThreadID()
{
return pthread_self();
}
inline pthread_t Thread::getThreadID()
{
return tid;
}
inline int Thread::getState()
{
return threadStatus;
}
void Thread::join()
{
if(tid > 0)
{
pthread_join(tid, NULL);
}
}
void Thread::join(unsigned long millisTime)
{
if(tid == 0){
return;
}
if(millisTime == 0)
{
join();
}else
{
unsigned long k=0;
while(threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
{
usleep(100);
k++;
}
}
}
bool Thread::operator==(const Thread *otherThread)
{
if(otherThread==NULL)
{
return false;
}
if(curThreadInitNumber==(*otherThread).curThreadInitNumber)
{
return true;
}
return false;
}
bool Thread::isEquals(Thread *iTarget)
{
if(iTarget==NULL)
{
return false;
}
return pthread_self()==iTarget->tid;
}
void Thread::setThreadScope(bool isSystem)
{
if(isSystem)
{
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
}else
{
pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
}
}
bool Thread::getThreadScope()
{
int scopeType=0;
pthread_attr_getscope(&attr,&scopeType);
return scopeType==PTHREAD_SCOPE_SYSTEM;
}
void Thread::setThreadPriority(int priority)
{
pthread_attr_getschedparam(&attr,¶m);
param.__sched_priority=priority;
pthread_attr_setschedparam(&attr,¶m);
}
int Thread::getThreadPriority()
{
pthread_attr_getschedparam(&attr,¶m);
return param.__sched_priority;
}
#ifndef TIMER_H_
#define TIMER_H_
#include "Thread.h"
#include
#include
class Timer:public Thread
{
public:
Timer(Runnable *iTarget):Thread(iTarget){start();}
void run();
void schedule(long delay, long period = 0);
bool isScheduled();
bool isIdle();
void reset();
void cancel();
void destroy();
private:
Runnable *_task;
long _delay;
long _period;
bool _scheduled;
bool _reset;
bool _stopped;
bool _canceled;
pthread_mutex_t _lock;
pthread_mutex_t mutex;
pthread_cond_t cond;
};
#endif
#include "Timer.h"
#include
using namespace std;
void Timer::run()
{
int rc;
while(!_stopped)
{
rc = pthread_mutex_lock(&mutex);
while (!_scheduled && !_stopped)
{
pthread_cond_wait(&cond,&mutex);
}
if (_stopped)
break;
rc = pthread_mutex_unlock(&mutex);
rc = pthread_mutex_lock(&_lock);
_reset = false;
_canceled = false;
if (_delay > 0)
{
try
{
pthread_cond_wait(&cond, &_lock); //需要转换为该接口函数需要的参数类型
}
catch(...)
{
cout<<"exception!"<run();
if (_period>0)
{
while(true)
{
rc = pthread_mutex_lock(&_lock);
_reset = false;
try
{
pthread_cond_wait(&cond, &_lock);
}
catch(...)
{
cout<<"exception"<run();
}
}
}
}
void Timer::schedule(long delay, long period)
{
int rc;
_delay = delay;
_period = period;
if (_scheduled)
cout<<"already scheduled"<