summaryrefslogtreecommitdiff
path: root/Ivy/ThreadedSocket.h
blob: ad33c3e3080007e52772ec54c26c890d36a72eb6 (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
// ThreadedSocket.h: interface for the CThreadedSocket class.
//
//////////////////////////////////////////////////////////////////////


#pragma once



class CThreadedSocket 
{

public:
	CThreadedSocket();
	virtual ~CThreadedSocket();
// Construction
public:
	int Create(unsigned int nSocketPort = 0, int nSocketType=SOCK_STREAM, const char * lpszSocketAddress = 0);

// Attributes
public:
	SOCKET m_hSocket;

	inline operator SOCKET() const	{ return m_hSocket; };
	
	void GetPeerName(ivy::string & rPeerAddress, unsigned int& rPeerPort);

	void GetSockName(ivy::string & rSocketAddress, unsigned int& rSocketPort);

// Operations
public:
	SOCKET Socket(int nSocketType=SOCK_STREAM, int nProtocolType = 0, int nAddressFormat = PF_INET);
	
	int AddMember( const char * lpszHostAddress );

	virtual SOCKET Accept(CThreadedSocket& rConnectedSocket,
		SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);

	int Bind(unsigned int nSocketPort, const char * lpszSocketAddress = 0);

	virtual void Close();

	int Connect(const char * lpszHostAddress, unsigned int nHostPort);
	int Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
	int Listen(int nConnectionBacklog=5);
	
	virtual size_t Receive(void* lpBuf, size_t nBufLen, int nFlags = 0);

	size_t ReceiveFrom(void* lpBuf, size_t nBufLen,
		ivy::string & rSocketAddress, unsigned int & rSocketPort, int nFlags = 0);

	enum { receives = 0, sends = 1, both = 2 };

	virtual size_t Send(const void* lpBuf, size_t nBufLen, int nFlags = 0);

	size_t SendTo(const void* lpBuf, size_t nBufLen,
		unsigned int nHostPort, const char * lpszHostAddress = 0, int nFlags = 0);
	

inline int GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
	{ 
	return getpeername(m_hSocket, lpSockAddr, lpSockAddrLen);
	}
inline int GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
	{
	return getsockname(m_hSocket, lpSockAddr, lpSockAddrLen);
	}
inline int SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET)
	{ 
	return setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen);
	}
inline int GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel = SOL_SOCKET)
	{
	return getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen);
	}

static inline int CThreadedSocket::GetLastError()
	{ return ::WSAGetLastError(); }
inline int Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
	{ 
	return bind(m_hSocket, lpSockAddr, nSockAddrLen);
	}

inline int IOCtl(long lCommand, unsigned long* lpArgument)
	{
	return ioctlsocket(m_hSocket, lCommand, lpArgument);
	}

inline size_t ReceiveFrom(void* lpBuf, size_t nBufLen, SOCKADDR* lpSockAddr, size_t* lpSockAddrLen, int nFlags = 0)
	{
	int len = (int)*lpSockAddrLen; // Non conforme a Unix
	size_t lg = recvfrom(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, &len); 
	*lpSockAddrLen = len;
	return lg;
	}
inline int ShutDown(int nHow = sends)
	{ 
	return shutdown(m_hSocket,nHow);
	}
inline size_t SendTo(const void* lpBuf, size_t nBufLen, const SOCKADDR* lpSockAddr, size_t nSockAddrLen, int nFlags = 0)
	{
	return  sendto(m_hSocket, (LPSTR)lpBuf, (int)nBufLen, nFlags, lpSockAddr, (int)nSockAddrLen);
	}


// Overridable callbacks
protected:
	virtual void OnReceive(int nErrorCode);
	virtual void OnSend(int nErrorCode);
	virtual void OnOutOfBandData(int nErrorCode);
	virtual void OnAccept(int nErrorCode);
	virtual void OnConnect(int nErrorCode);
	virtual void OnClose(int nErrorCode);
// Implementation 
	int StartListener();
	int StartWriter();
	bool SignalWriter();

	HANDLE h_reader;
	HANDLE h_writer;
	unsigned long reader_id;
	unsigned long writer_id;
	unsigned int SocketReader();	//Receiver Thread
	unsigned int SocketWriter();	//Sender Thread
	bool listen_mode;
	bool connect_pending;
	bool send_pending;
	HANDLE send_count;


// wrapper for thread routine
static DWORD WINAPI SocketReaderProc( void * pParam );
static DWORD WINAPI SocketWriterProc( void * pParam );

};