summaryrefslogtreecommitdiffstats
path: root/src/uscxml/server/Socket.h
blob: 01e91b2fb60ef8f02e7121c95a59a32f83544061 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 *  @file
 *  @author     2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de)
 *  @copyright  Simplified BSD
 *
 *  @cond
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the FreeBSD license as published by the FreeBSD
 *  project.
 *
 *  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.
 *
 *  You should have received a copy of the FreeBSD license along with this
 *  program. If not, see <http://www.opensource.org/licenses/bsd-license>.
 *  @endcond
 */

#ifndef SOCKETCLIENT_H_9A0B2A88
#define SOCKETCLIENT_H_9A0B2A88

#include "uscxml/Common.h"              // for USCXML_API
#include "uscxml/concurrency/EventBase.h"
#include <string>
#include <sstream>
#include <map>
#include <set>

#ifdef _WIN32
#	include <winsock2.h>
#else
#	include <netinet/in.h> /* For sockaddr_in */
#endif
#include <cerrno>

#include "uscxml/concurrency/tinythread.h"  // for recursive_mutex, etc

extern "C" {
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>
}

namespace uscxml {

class USCXML_API Socket {
public:
	Socket(int domain, int type, int protocol);
	virtual ~Socket();

	void setBlockSizeRead(size_t size);
	static void parseAddress(const std::string& address, std::string& protocol, std::string& hostName, uint16_t& port);

protected:

	void setupSockAddr(const std::string& address, int port);

	evutil_socket_t _socketFD;

	tthread::recursive_mutex _mutex;
	size_t _blockSizeRead;
	struct sockaddr_in _sin;

	boost::shared_ptr<EventBase> _base;
};

class USCXML_API ServerSocket : public Socket {
public:
	class Connection {
	public:
		bool operator<(const Connection& other) const {
			return bufferEvent < other.bufferEvent;
		}

		struct bufferevent* bufferEvent;
		int fd;

		void reply(const char* data, size_t size);
	};

	ServerSocket(int domain, int type, int protocol);
	virtual ~ServerSocket();

	void listen(const std::string& address, int port);
	void listen(const std::string& address);
	virtual void readCallback(const char* data, size_t size, Connection& conn) {};


protected:
	void bind();
	static void acceptCallback(evutil_socket_t listener, short event, void *ctx);
	static void errorCallback(struct bufferevent *bev, short error, void *ctx);
	static void readCallback(struct bufferevent *bev, void *ctx);

	std::map<struct bufferevent*, Connection> _connections;
	struct event* _listenerEvent;

	static std::set<ServerSocket*> _instances;

};

class USCXML_API PacketServerSocket : public ServerSocket {
public:
	PacketServerSocket(int domain, int type, int protocol, const std::string& sep) : ServerSocket(domain, type, protocol), _sep(sep) {}
	virtual ~PacketServerSocket();

	void readCallback(const char* data, size_t size, Connection& conn);
	virtual void readCallback(const std::string& packet, Connection& conn) = 0;

protected:
	std::string _sep;
	std::map<Connection, std::stringstream*> _fragments;
};

class USCXML_API ClientSocket : public Socket {
public:
	ClientSocket(int domain, int type, int protocol);
	virtual ~ClientSocket();

	virtual void readCallback(const char* data, size_t size) {};
	void connect(const std::string& address, int port);
	void connect(const std::string& address);
	int write(const std::string& data);
	int write(const char* data, size_t size);


protected:
	static void readCallback(struct bufferevent *bev, void *ctx);
	static void errorCallback(struct bufferevent *bev, short error, void *ctx);

	struct bufferevent* _clientEvent;

};


}

#endif /* end of include guard: SOCKETCLIENT_H_9A0B2A88 */