⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.cpp

📁 J-Alice是一个用C++实现的Ailcebot的克隆。它可以做为一个mini-http服务器在控制台或irc聊天。目前
💻 CPP
字号:
#include "Socket.h"#include "Logger.h"	//	LOGGING FACILITY#ifdef WIN32 #include <winsock2.h>#else #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h>#endif#include <unistd.h>#include <stdio.h>#include <errno.h>#include "SocketHandler.h"#include <iostream>#include "Compat.h"#include "Utils.h"using namespace std;#ifdef WIN32	extern "C" {		void win32_init_sockets(void);				int winsock_handle = -1;		int socket_count = 0;				void win32_init_sockets(void) {			WSADATA d;						if (winsock_handle == -1) {				winsock_handle = WSAStartup(MAKEWORD(2, 0), &d);			}		}	}	#define EWOULDBLOCK WSAEWOULDBLOCK #endifSocket::Socket(int socket, const char* name, int p):listener(NULL), sd(socket),		port(p), host(name) {	//	Needed for inheritance	#ifdef WIN32		win32_init_sockets();	#endif	SocketHandler::addSocket(this);}Socket::Socket(const string &host, const int &port) {	this->host = mystrdup(host.c_str());	this->port = port;	#ifdef WIN32		win32_init_sockets();	#endif	listener = NULL;	sd = -1;		struct sockaddr_in sa;		if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket");		disconnect("socket() failed");		return;	}		sa.sin_family = AF_INET;	sa.sin_addr.s_addr = htonl(INADDR_ANY);	sa.sin_port = htons(0);	memset(sa.sin_zero, 0, sizeof(sa.sin_zero));		if (bind(sd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {		//	This isn't lethal .. can still continue		perror("bind");	}		SocketHandler::addSocket(this);}Socket::~Socket() {	disconnect();	//TODO: remove self from the socket loop//	As far as I can tell, this don't work//	for (int ix = 0; ix < SocketHandler::sockets.size(); ++ix) {//		if (SocketHandler::sockets[ix] == this) {//			SocketHandler::sockets[ix]->process();//			SocketHandler::sockets[ix] = NULL;//		}//	}	delete [] host;	host = NULL;}const int buffer_size = 5000;void Socket::connect() {	if (sd < 0) {		//	Constructing the socket failed previously		if (listener != NULL) {			listener->disconnected("couldn't create socket");		}	}	struct sockaddr_in sa;	struct hostent *he;		he = gethostbyname(host);	if (he == NULL) {		disconnect(string(string(host) + " unknown").c_str());		Logger::log(string(host) + " could not be found [unknown host]", "networking");		return;	}		sa.sin_family = he->h_addrtype;	memcpy((char *)&sa.sin_addr.s_addr, he->h_addr_list[0], he->h_length);	sa.sin_port = htons(port);	memset(sa.sin_zero, 0, sizeof(sa.sin_zero));		if (::connect(sd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {		disconnect(string("failed connect to "+ string(host)).c_str());		Logger::log("connection to " + string(host) + " failed", "networking");		return;	}	if (listener != NULL) {		listener->connected();	}}void Socket::disconnect(const char *reason) {	string out = "";	if (reason != NULL) {		if (host == NULL) {			out = string(reason);		} else {			out = string(host) + ": " + string(reason);		}	}	if (sd != -1) {		closesocket(sd);		sd = -1;		if (listener != NULL) {			listener->disconnected(out);		}	}}void Socket::setListener(SocketListener *listener) {	this->listener = listener;}SocketListener *Socket::getListener() {	return listener;}int Socket::getSD() {	return sd;}void Socket::process() {	//	This gets called from SocketHandler when we	//	have something waiting for us (data)	string str;	read(str);}int Socket::read(string &str) {	int n = 0;	int buf_size = buffer_size;	if (buf_size > 1) {		--buf_size;	}	char *buffer = new char[buffer_size];	n = read_raw(buffer, buf_size);	buffer[n] = '\0';	str = string(buffer);	if (listener != NULL) {		listener->recv(str);	}	return n;}int Socket::write(const string &str, bool appendNullByte) {	int n = write_raw(str.c_str(), str.length());	if (appendNullByte && n >= 0) {		char ch = '\0';		return n + write_raw(&ch, 1);	}	return n;}int Socket::read_raw(void *buffer, int buf_size) {	int n = 0;	if (sd < 0) {		return n;	}		#ifdef WIN32		n = recv(sd, (char FAR *)buffer, buf_size, 0);	#else		n = recv(sd, (char *)buffer, buf_size, 0);	#endif	if (n < 0) {		if (errno != EWOULDBLOCK) {			perror("recv");			disconnect("error receiving data");		}	} else if (n == 0) {		disconnect("connection closed by peer");	}	return n;}int Socket::write_raw(const void *data, int len) {	int ret;	if (sd == -1) {		return 0;	}	#ifdef WIN32		ret = send(sd, (char FAR *)data, len, 0);	#else		ret = send(sd, (const char *)data, len, 0);	#endif	if (ret < 0){		perror("send");		disconnect();	}	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -