summaryrefslogtreecommitdiff
path: root/Ivy/ThreadedSocket.h
blob: 1827c52af8760c1a03458cc030b9fc427d3a6bb6 (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
// 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;

	operator SOCKET() const;
	
	void GetPeerName(string & rPeerAddress, unsigned int& rPeerPort);

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

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

	virtual int 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 int Receive(void* lpBuf, int nBufLen, int nFlags = 0);

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

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

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

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

	
inline CThreadedSocket::operator SOCKET() const
	{ return m_hSocket; }
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 int ReceiveFrom(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0)
	{
	int lg = recvfrom(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen); 
	return lg;
	}
inline int ShutDown(int nHow = sends)
	{ 
	return shutdown(m_hSocket,nHow);
	}
inline int SendTo(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0)
	{
	return  sendto(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, 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 );

};