?? bufferedsocket.h
字號:
/*
* Copyright (C) 2001-2003 Jacek Sieka, j_s@telia.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined(AFX_BUFFEREDSOCKET_H__0760BAF6_91F5_481F_BFF7_7CA192EE44CC__INCLUDED_)
#define AFX_BUFFEREDSOCKET_H__0760BAF6_91F5_481F_BFF7_7CA192EE44CC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Semaphore.h"
#include "Thread.h"
#include "Speaker.h"
class File;
class BufferedSocketListener {
public:
typedef BufferedSocketListener* Ptr;
typedef vector<Ptr> List;
typedef List::iterator Iter;
enum Types {
CONNECTING,
CONNECTED,
LINE,
DATA,
BYTES_SENT,
MODE_CHANGE,
TRANSMIT_DONE,
FAILED
};
virtual void onAction(Types) throw() { };
virtual void onAction(Types, u_int32_t) throw() { };
virtual void onAction(Types, const string&) throw() { };
virtual void onAction(Types, const u_int8_t*, int) throw() { };
virtual void onAction(Types, int) throw() { };
};
class ZCompressor;
class BufferedSocket : public Speaker<BufferedSocketListener>, public Socket, public Thread
{
public:
enum {
MODE_LINE,
MODE_DATA
};
enum Tasks {
CONNECT,
DISCONNECT,
SEND_DATA,
SEND_FILE,
SHUTDOWN
};
/**
* BufferedSocket factory
* @param sep Line separator
* @return An unconnected socket
*/
static BufferedSocket* getSocket(char sep) throw(SocketException) {
return new BufferedSocket(sep);
};
static void putSocket(BufferedSocket* aSock) {
aSock->removeListeners();
aSock->Socket::disconnect();
Lock l(aSock->cs);
aSock->addTask(SHUTDOWN);
};
// Socket::accept is ok for buffered sockets as well! (Note; it's synchronous tho...)
// virtual void accept(const ServerSocket& srv) throw(SocketException) { Socket::accept(srv); }
virtual void disconnect() {
Lock l(cs);
addTask(DISCONNECT);
}
/**
* Sets data mode for aBytes bytes long. Must be called within an action method...
*/
void setDataMode(int64_t aBytes = -1) {
mode = MODE_DATA;
dataBytes = aBytes;
}
/**
* Should be called when data mode.
*/
void setLineMode() {
dcassert(mode == MODE_DATA);
dcassert(dataBytes == -1);
mode = MODE_LINE;
}
int getMode() { return mode; };
/**
* Connect to aServer / aPort
* Note; this one doesn't actually throw, but it overrides one that does...
*/
virtual void connect(const string& aServer, short aPort) throw(SocketException) {
Lock l(cs);
mode = MODE_LINE;
server = aServer;
port = aPort;
addTask(CONNECT);
}
void write(const string& aData) throw(SocketException) { write(aData.data(), aData.length()); };
virtual void write(const char* aBuf, int aLen) throw();
/**
* Send the file f over this socket.
*/
void transmitFile(File* f, int64_t s, bool docomp = false) throw() {
Lock l(cs);
file = f;
size = s;
compress = docomp;
addTask(SEND_FILE);
}
GETSET(char, separator, Separator);
private:
BufferedSocket(char aSeparator = 0x0a) throw(SocketException) : separator(aSeparator), port(0), mode(MODE_LINE),
dataBytes(0), inbufSize(16*1024), curBuf(0), comp(NULL), compress(false), file(NULL), size(0) {
inbuf = new u_int8_t[inbufSize];
// MSVC: Non-standard scope for i
{
for(int i = 0; i < BUFFERS; i++) {
outbuf[i] = new u_int8_t[inbufSize];
outbufPos[i] = 0;
outbufSize[i] = inbufSize;
}
}
try {
start();
} catch(const ThreadException& e) {
delete[] inbuf;
for(int i = 0; i < BUFFERS; i++) {
delete[] outbuf[i];
}
throw SocketException(e.getError());
}
};
// Dummy...
BufferedSocket(const BufferedSocket&) throw() { dcassert(0); };
bool fillBuffer(char* buf, int bufLen, u_int32_t timeout = 0) throw(SocketException);
virtual ~BufferedSocket() {
delete[] inbuf;
for(int i = 0; i < BUFFERS; i++) {
}
}
CriticalSection cs;
Semaphore taskSem;
vector<Tasks> tasks;
string server;
short port;
int mode;
int64_t dataBytes;
string line;
u_int8_t* inbuf;
size_t inbufSize;
enum {BUFFERS = 2};
u_int8_t* outbuf[BUFFERS];
int outbufSize[BUFFERS];
int outbufPos[BUFFERS];
int curBuf;
ZCompressor* comp;
bool compress;
File* file;
int64_t size;
virtual void create(int) throw(SocketException) { dcassert(0); }; // Sockets are created implicitly
virtual void bind(short) throw(SocketException) { dcassert(0); }; // Binding / UDP not supported...
virtual int run();
void threadConnect();
void threadRead();
bool threadSendFile();
void threadSendData();
void threadDisconnect();
void fail(const string& aError) {
Socket::disconnect();
fire(BufferedSocketListener::FAILED, aError);
}
/**
* Shut down the socket and delete itself...no variables must be referenced after
* calling threadShutDown, the thread function should exit as soon as possible
*/
void threadShutDown() {
removeListeners();
delete this;
}
void addTask(Tasks task) {
tasks.push_back(task);
taskSem.signal();
}
};
#endif // !defined(AFX_BUFFEREDSOCKET_H__0760BAF6_91F5_481F_BFF7_7CA192EE44CC__INCLUDED_)
/**
* @file
* $Id: BufferedSocket.h,v 1.48 2003/07/15 14:53:10 arnetheduck Exp $
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -