Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / 2 / lab.03.by mice / claw / fake_socket

.cpp
Скачиваний:
10
Добавлен:
17.04.2013
Размер:
3.99 Кб
Скачать
/*******************************************************************************
* file:         fake_socket.cpp                                                *
* version:      0.0.1                                                          *
* author:       d-evil [tmd] (mailto:d-evil.tmd@mail.ru)                       *
* description:  not available                                                  *
*******************************************************************************/

#include "fake_socket.h"


////////////////////////////////////////////////////////////////////////////////
// CSocket public definition
CSocket::CSocket() {
	_sock = INVALID_SOCKET;

	_type = SOCK_STREAM;
	_iaddr.set_to_local();

	_is_binded = false;
	_is_connected = false;
}

CSocket::~CSocket() {
	Close();
}


int CSocket::Create(unsigned short port, int type, long event, char *addr) {
	Close();
	_type = type;
	if (0 != port) _iaddr.set_port(port);
	if (NULL != addr) _iaddr.set_host(addr);

	_sock = socket(AF_INET, type, IPPROTO_TCP);
	if (INVALID_SOCKET == _sock) return -1;

	return 0;
}


int CSocket::Bind(int port, const char *const host) {
	if (0 != port) _iaddr.set_port(port);
	if (NULL != host) _iaddr.set_host(host);

	if (0 != bind(_sock, _iaddr.saddr(), _iaddr.saddr_sz())) return -1;

	_is_binded = true;
	return 0;
}


int CSocket::Listen(const int backlog) {
	if (0 != listen(_sock, backlog)) return -1;

	sockaddr_in sa;
	int n = sizeof(sa);
	getsockname(_sock, (sockaddr *)&sa, &n);

	return 0;
}


int CSocket::CanRead(const int timeout_ms) {
	fd_set set;
	set.fd_count = 1;
	set.fd_array[0] = _sock;

	timeval to;
	to.tv_sec = 0;
	to.tv_usec = timeout_ms * 100;

	int rev = select(0, &set, NULL, NULL, &to);
	switch (rev) {
		case SOCKET_ERROR: return -1;
		case 0: return 0;
		default: return 1;
	}

	return -1;	// dummy return
}


int CSocket::CanWrite(const int timeout_ms) {
	fd_set set;
	set.fd_count = 1;
	set.fd_array[0] = _sock;

	timeval to;
	to.tv_sec = 0;
	to.tv_usec = timeout_ms * 100;

	int rev = select(0, NULL, &set, NULL, &to);
	switch (rev) {
		case SOCKET_ERROR: return -1;
		case 0: return 0;
		default: return 1;
	}

	return -1;	// dummy return
}


int CSocket::Accept(CSocket& csock, sockaddr *const saddr, int *const saddr_sz) {
	sockaddr_in lsa;
	int lsa_sz = sizeof(lsa);
	SOCKET acs = accept(_sock, (sockaddr *)&lsa, &lsa_sz);
	if (INVALID_SOCKET == acs) return -1;

	csock.Close();
	csock._sock = acs;
	csock.iaddr()->set(&lsa);
	csock._is_connected = true;

	if (NULL == saddr_sz) return 0;
	if (NULL == saddr) return 0;
	if (*saddr_sz == lsa_sz) {
		memcpy(saddr, &lsa, lsa_sz);
	}
	*saddr_sz = lsa_sz;
	
	return 0;
}


int CSocket::Connect(const sockaddr *const saddr, const int saddr_sz) {
	if (NULL != saddr) _iaddr.set((sockaddr_in *)saddr);

	if (0 != connect(_sock, _iaddr.saddr(), _iaddr.saddr_sz())) return -1;

	_is_connected = true;
	return 0;
}


int CSocket::Attach(const SOCKET sock) {
	if (INVALID_SOCKET == sock) return -1;

	_sock = sock;
	sockaddr_in saddr;
	int saddr_sz = sizeof(saddr);

	if (0 != getsockname(_sock, (sockaddr *)&saddr, &saddr_sz)) return -1;

	return _iaddr.set(&saddr);
}


int CSocket::Receive(char *const buf, const int buf_sz, const int flags) {
	int rev = recv(_sock, buf, buf_sz, flags);
	if (SOCKET_ERROR == rev) return -1;

	return rev;
}


int CSocket::Send(const char *const buf, const int buf_sz, const int flags) {
	int rev = send(_sock, buf, buf_sz, flags);
	if (SOCKET_ERROR == rev) return -1;

	return rev;
}


int CSocket::Close() {
	if (INVALID_SOCKET == _sock) return 0;
	if (0 != closesocket(_sock)) return -1;

	_sock = INVALID_SOCKET;
	_is_binded = false;
	_is_connected = false;
	return 0;
}



////////////////////////////////////////////////////////////////////////////////
// CSocket protected definition
Соседние файлы в папке claw