Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
11
Добавлен:
17.04.2013
Размер:
12.3 Кб
Скачать
/*******************************************************************************
* file:         fx_net.h                                                       *
* version:	    0.0.1                                                          *
* author:       inba (mailto:inba@mail.ru)                                     *
* description:  not available                                                  *
*******************************************************************************/

#ifndef FX_NET_INCLUDED
#define FX_NET_INCLUDED

////////////////////////////////////////////////////////////////////////////////
// for correct linkage order
#include <afx.h>


////////////////////////////////////////////////////////////////////////////////
// standart headers
#include <stdio.h>


////////////////////////////////////////////////////////////////////////////////
// OS depended headers
#include <winsock2.h>


////////////////////////////////////////////////////////////////////////////////
// program specific headers
#include "fx_const.h"
#include "fx_fblk.h"


namespace fx_ns {

/*******************************************************************************
*  declarations                                                                *
*******************************************************************************/

////////////////////////////////////////////////////////////////////////////////
// types
struct sfx_header {
	char filename[LEN_FILEPATH];
	unsigned int filesize;
};


////////////////////////////////////////////////////////////////////////////////
// functions
WORD version_required();	// declaration

// #define TO_PVOID(int_val)	(reinterpret_cast<void *>(int_val))
#define TO_PVOID(int_val)	(*(void **)&int_val)
// #define TO_INT(void_ptr)	(reinterpret_cast<int>(void_ptr))
#define TO_INT(void_ptr)	(*(int *)&void_ptr)


////////////////////////////////////////////////////////////////////////////////
// cfx_socket (declaration)
class cfx_socket;
typedef int (* tfx_socket_event)(const int event, cfx_socket *const caller, void *const data);


class cfx_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// error codes
	static const int ERC_SOCK_CLOSE	= 4010;

	cfx_socket();
	cfx_socket(void *const owner, const tfx_socket_event ev_handler = NULL, void *const ext_id = NULL);
	~cfx_socket();

	SOCKET sock() const { return _socket; }
	void *owner() const { return _owner; }
	void set_owner(void *const owner) { _owner = owner; }
	void *ext_id() const { return _ext_id; }
	void set_ext_id(void *const ext_id) { _ext_id = ext_id; }
	sockaddr_in *saddr_in() { return &_saddr_in; }
	int saddr_in_sz() const { return sizeof(_saddr_in); }
	tfx_socket_event get_ev_handler() const { return _on_event; }
	void set_ev_handler(const tfx_socket_event handler) { _on_event = handler; }
	static int resolve_addr(const char *const addr, in_addr *const raddr);
	void set_linger(unsigned short on_off, unsigned short t);
	void get_linger(unsigned short *on_off, unsigned short *t) const;
	int last_error() const { return _last_error; }

	int create();
	int create(const SOCKET sock, const sockaddr_in *const saddr_in);
	int kill();

	// Event:  EV_ERROR
	// data:   error code (converted to int)
	// values: ERC_XXXXX constants
	// return: not used
	static const int EV_ERROR = 6001;

protected:
	inline int _call_event(const int event, void *const data) {
		return (NULL != _on_event)? _on_event(event, this, data): ERC_NOTHANDLED;
	}
	int _wsa_error(const int er = 0) { _last_error = WSAGetLastError(); return er;}
	int _not_wsa_error(const int er = 0) { _last_error = GetLastError(); return er; }
	int _set_error(const int er) { return _last_error = er; }

	HANDLE kill_mtx() const { return _kill_mtx; }


private:
	SOCKET _socket;
	sockaddr_in _saddr_in;
	int _last_error;
	void *_owner;
	void *_ext_id;	// external identificator
	HANDLE _kill_mtx;
	tfx_socket_event _on_event;

};



////////////////////////////////////////////////////////////////////////////////
// cfx_server (declaration)
class cfx_client;
class cfx_server: public cfx_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// types
	struct sfx_accept_struct {
		SOCKET asock;
		sockaddr_in addr;
		int addr_len;
	};


	////////////////////////////////////////////////////////////////////////////
	// error codes
	static const int ERC_SERV_CANTSTOPS	= -4310;
	static const int ERC_SERV_CANTSTOPC	= -4315;
	static const int ERC_SERV_INVSOCKAC	= -4320;


	////////////////////////////////////////////////////////////////////////////
	// events

	// Event:  EV_STOPPING
	// data:   reason (converted to int)
	// values: EV_STR_NORM - on internal normal reasons
	//         EV_STR_USER - on user request (server::stop)
	//         ERC_XXX - on error
	// return: OK_CANCEL - try to cancel stopping
	static const int EV_STOPPING	= 6101;
	static const int EV_STR_NORM	= 6102;
	static const int EV_STR_USER	= 6103;

	// Event:  EV_STOPED
	// data:   reason (converted to int)
	// values: EV_STR_NORM - on internal normal reasons
	//         EV_STR_USER - on user request (server::stop)
	//         ERC_XXX - on error
	// return: not used (must be OK_OK)
	static const int EV_STOPED		= 6110;

	// Event:  EV_LISTENING
	// data:   not used (must be NULL)
	// return: not used (must be OK_OK)
	static const int EV_LISTENING	= 6120;

	// Event:  EV_ACCEPTING
	// data:   pointer to sfx_accept_struct
	// return: OK_OK to accept conection
	//         OK_CANCEL to discard it
	static const int EV_ACCEPTING	= 6130;

	// Event:  EV_ACCEPTED
	// data:   pointer to cfx_client object
	// return: OK_OK to accept the cfx_client object
	static const int EV_ACCEPTED	= 6140;


	cfx_server(): cfx_socket() { _init(); }
	cfx_server(void *const owner, const tfx_socket_event ev_handler = NULL, void *const ext_id = NULL):
				cfx_socket(owner, ev_handler, ext_id) { _init(); }
	~cfx_server();

	int get_max_pc() const { return _mx_pc; }
	void set_max_pc(const int mx_pc) { _mx_pc = mx_pc; }
	int get_buf_size() const { return _buf_sz; }
	void set_buf_size(const int buf_sz) { _buf_sz = buf_sz; }

	int bind(const char *const addr, const unsigned short port);
	int run();
	int stop();
	int kill(const bool wait = true);

	cfx_client *new_client() const;
	void del_client(cfx_client *clnt);

protected:
	void _init();
	static DWORD __stdcall _accept_proc(cfx_server *const server);

private:
	bool _stoped;
	SOCKET _fs_sock;
	DWORD _accept_thread_id;
	HANDLE _accept_thread_h;

	int _mx_pc;
	static const int _def_mx_pc = 8;
	int _buf_sz;
	static const int _def_buf_sz = 0xFFFF;

};


////////////////////////////////////////////////////////////////////////////////
// cfx_client (declaration)
class cfx_client: public cfx_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// types
	struct sfx_file_info {
		unsigned int total_sz;

		unsigned int done_sz;

		char *buf;
		int buf_sz;

		char *filename;
		FILE *file;
	};


	////////////////////////////////////////////////////////////////////////////
	// client events

	// Event:  EV_WAITING4DATA
	// data:   not used (must be NULL)
	// return: OK_OK to continue waiting
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_WAITING4DATA = 6203;

	// Event:  EV_RECVING_INFO
	// data:   not used (must be NULL)
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_RECVING_INFO = 6204;

	// Event:  EV_RECVED_INFO
	// data:   pointer to sfx_file_info structure
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_RECVED_INFO = 6205;

	// Event:  EV_NEED_FILE2W
	// data:   pointer to sfx_file_info structure
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_NEED_FILE2W = 6206;

	// Event:  EV_NEED_FILE2R
	// data:   pointer to sfx_file_info structure
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_NEED_FILE2R = 6207;

	// Event:  EV_RECVING_DATA
	// data:   pointer to sfx_file_info structure
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_RECVING_DATA = 6208;

	// Event:  EV_RECVED_DATA
	// data:   pointer to sfx_file_info structure
	// return: OK_OK to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_RECVED_DATA = 6209;

	// Event:  EV_RECV_END
	// data:   reason
	// values: OK_OK - no more data available
	//         ...
	// return: OK_ to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_RECV_END = 6210;
	static const int EV_RECV_DONE = 6230;

	// Event:  EV_SENDING_INFO
	// data:   not used (must be NULL)
	// return: OK_ to continue sending
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SENDING_INFO = 6211;

	// Event:  EV_SENT_INFO
	// data:   pointer to sfx_file_info structure
	// return: OK_ to continue sending
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SENT_INFO = 6212;

	// Event:  EV_SENDING_DATA
	// data:   pointer to sfx_file_info structure
	// return: OK_ to continue sending
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SENDING_DATA = 6213;

	// Event:  EV_SENT_DATA
	// data:   pointer to sfx_file_info structure
	// return: OK_ to continue sending
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SENT_DATA = 6214;

	// Event:  EV_SEND_DONE
	// data:   pointer to sfx_file_info structure
	// return: OK_ to continue sending
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SEND_DONE = 6215;

	// Event:  EV_SEND_END
	// data:   reason
	// values: OK_OK - no more data available
	//         ...
	// return: OK_ to continue receiving
	//         OK_CANCEL to abort operation
	//         or error code
	static const int EV_SEND_END = 6216;

	// Event:  EV_KILLING
	// data:   reason
	// values: OK_OK normal killing process
	//         ERC_XX on error
	// return: not used (must be OK_OK)
	static const int EV_KILLING = 6220;

	// Event:  EV_KILLING
	// data:   not used (must be NULL)
	// return: not used (must be OK_OK)
	static const int EV_KILLED = 6225;

	////////////////////////////////////////////////////////////////////////////
	// error codes
	static const int ERC_CLNT_CANTOPNFL	= -4705;
	static const int ERC_CLNT_CANTCRFL	= -4710;
	static const int ERC_CLNT_ERRECV	= -4715;
	static const int ERC_CLNT_ERSEND	= -4720;
	static const int ERC_CLNT_SZ_DM	= -4725;

	cfx_client(): cfx_socket() { _init(); }
	cfx_client(void *const owner, const tfx_socket_event ev_handler = NULL, void *const ext_id = NULL):
				cfx_socket(owner, ev_handler, ext_id) { _init(); }

	int connect(const char *const addr, const unsigned short port);
	int send_file(char *const filename);
	int recv_file();

	cfx_server *parent() const { return _parent; }
	void set_parent(cfx_server *const parent) { _parent = parent; }
	int get_buf_size() const { return _buf_sz; }
	void set_buf_size(const int buf_sz) { _buf_sz = buf_sz; }
	char *get_fname() const { return _filename; }
	void set_fname(char *const fname) { _filename = fname; }

protected:
	void _init();
	static DWORD __stdcall _recv_proc(cfx_client *const client);
	static DWORD __stdcall _send_proc(cfx_client *const client);

private:
	cfx_server *_parent;

	DWORD _thread_id;
	HANDLE _thread_h;

	char *_filename;
	int _buf_sz;
	static const int _def_buf_sz = 0xFFFF;

};



};	// end of namespace "fx_ns"



#endif FX_NET
Соседние файлы в папке fexchange