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
|
/*****************************************************************************/
/* Sockets.h Copyright (c) Ladislav Zezula 2021 */
/*---------------------------------------------------------------------------*/
/* MIME parsing functions for CascLib */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 13.02.21 1.00 Lad Created */
/*****************************************************************************/
#ifndef __SOCKET_H__
#define __SOCKET_H__
//-----------------------------------------------------------------------------
// Defines
#ifndef SOCKET_ERROR
#define SOCKET_ERROR (-1)
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#ifndef WSAECONNRESET
#define WSAECONNRESET 10054L
#endif
#ifndef EPIPE
#define EPIPE 32
#endif
#define CASC_PORT_HTTP 80
#define CASC_PORT_RIBBIT 1119
//-----------------------------------------------------------------------------
// The CASC_SOCKET class
typedef class CASC_SOCKET_CACHE * PCASC_SOCKET_CACHE;
typedef class CASC_SOCKET * PCASC_SOCKET;
typedef struct addrinfo * PADDRINFO;
class CASC_SOCKET
{
public:
char * ReadResponse(const char * request, size_t request_length, CASC_MIME_RESPONSE & MimeResponse);
DWORD AddRef();
void Release();
private:
// Constructor and destructor
static int GetSockError();
static DWORD GetAddrInfoWrapper(const char * hostName, unsigned portNum, PADDRINFO hints, PADDRINFO * ppResult);
static HANDLE CreateAndConnect(PADDRINFO remoteItem);
static HANDLE ReconnectAfterShutdown(HANDLE & sock, PADDRINFO remoteItem);
static PCASC_SOCKET New(PADDRINFO remoteList, PADDRINFO remoteItem, const char * hostName, unsigned portNum, HANDLE sock);
static PCASC_SOCKET Connect(const char * hostName, unsigned portNum);
// Frees all resources and deletes the socket
void Delete();
// Entities allowed to manipulate with the class
friend CASC_SOCKET * sockets_connect(const char * hostName, unsigned portNum);
friend char * sockets_read_response(PCASC_SOCKET pSocket, const char * request, size_t request_length, size_t * PtrLength);
friend class CASC_SOCKET_CACHE;
PCASC_SOCKET_CACHE pCache; // Pointer to the cache. If NULL, the socket is not cached
PCASC_SOCKET pPrev; // Pointer to the prev socket in the list
PCASC_SOCKET pNext; // Pointer to the next socket in the list
PADDRINFO remoteList; // List of the remote host informations
PADDRINFO remoteItem; // The particular host picked during the last connection attempt
CASC_LOCK Lock; // Lock for single threaded access
HANDLE sock; // Opened and connected socket
DWORD dwRefCount; // Number of references
DWORD portNum; // Port number
char hostName[1]; // Buffer for storing remote host (variable length)
};
//-----------------------------------------------------------------------------
// Socket cache class
class CASC_SOCKET_CACHE
{
public:
CASC_SOCKET_CACHE();
~CASC_SOCKET_CACHE();
PCASC_SOCKET Find(const char * hostName, unsigned portNum);
PCASC_SOCKET InsertSocket(PCASC_SOCKET pSocket);
void UnlinkSocket(PCASC_SOCKET pSocket);
void SetCaching(bool bAddRef);
void PurgeAll();
private:
PCASC_SOCKET pFirst;
PCASC_SOCKET pLast;
DWORD dwRefCount;
};
//-----------------------------------------------------------------------------
// Public functions
PCASC_SOCKET sockets_connect(const char * hostName, unsigned portNum);
void sockets_set_caching(bool caching);
#endif // __SOCKET_H__
|