229 lines
8.3 KiB
C
Raw Permalink Normal View History

2024-04-01 18:26:14 +08:00
/*
** Copyright 2003-2009, Ernest Laurentin (http://www.ernzo.com/)
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** File: SocketHandle.h
** Version: 1.4 - IPv6 support
** 1.3 - Update for Asynchronous mode / Linux port
** 1.2 - Update interface for TCP remote connection
** 1.1 - Added multicast support
*/
#ifndef SOCKETHANDLE_H
#define SOCKETHANDLE_H
#include <WinSock2.h>
#include <WS2tcpip.h>
/**
* CSocketHandle class
* Socket communication class
*/
class CSocketHandle
{
public:
/**
* Default constructor
*/
CSocketHandle();
/**
* Destructor
*/
~CSocketHandle();
/**
* Check if socket is opened
* @return true if this is opened (valid)
*/
bool IsOpen() const;
/**
* Get SOCKET handle
* @return SOCKET handle (handle is INVALID_SOCKET if object is closed)
*/
SOCKET GetSocket() const;
/**
* Attach a socket handle
* This function may fail is socket handle is not valid or object already in used. Call Detach or Close to release object.
* @param sock Socket handle to attach to this class
* @return true if successful, otherwise false
*/
bool Attach(SOCKET sock);
/**
* Detach a socket handle
* @return previous socket handle or INVALID_SOCKET
*/
SOCKET Detach();
/**
* Create a Socket - Server side.
* @param pszHost hostname or IP address of adapter
* @param pszServiceName Network service name or port number
* @param nFamily address family to use (AF_INET, AF_INET6)
* @param nType type of socket to create (SOCK_STREAM, SOCK_DGRAM)
* @param uOptions Additional options (SO_BROADCAST, SO_REUSEADDR)
* @return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error)
* @sa InitLibrary, ConnectTo, IsOpen
*/
bool CreateSocket(LPCTSTR pszHost, int port, int nFamily, int nType, UINT uOptions = 0);
/**
* Create a socket, connect to a server - Client side.
* @param pszHostName Hostname or NIC address
* @param pszRemote Remote network address
* @param pszServiceName Network service name or port number
* @param nFamily address family to use (AF_INET, AF_INET6)
* @param nType type of socket to create (SOCK_STREAM, SOCK_DGRAM)
* @return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error)
* @sa InitLibrary, CreateSocket, IsOpen
*/
bool ConnectTo(LPCTSTR pszRemote, int port, int nFamily, int nType,long timeout);
/**
* Close Socket
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen
*/
void Close();
/**
* Read from socket
* @param lpBuffer Buffer to receive data
* @param dwSize Size of buffer in bytes
* @param lpAddrIn Peer address for UDP - this must be NULL for TCP
* @param dwTimeout Read timeout in milliseconds
* @return number of bytes read or (-1L) if fail
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, Write, WriteEx
*/
int Read(LPBYTE lpBuffer, int dwSize, LPSOCKADDR lpAddrIn = NULL, long dwTimeout = INFINITE);
#ifdef WIN32
/**
* Read from socket (asynchronous mode).
* @param lpBuffer Buffer to receive data
* @param dwSize Size of buffer in bytes
* @param lpAddrIn SockAddrIn for UDP - this must be NULL for TCP
* @param lpOverlapped Windows Overlapped structure (required)
* @param lpCompletionRoutine Winsock Completion routine (required)
* @return number of bytes read, overlapped operation is pending or (-1L) if fail
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, Write, WriteEx, IOControl, GetTransferOverlappedResult
*/
DWORD ReadEx(LPBYTE lpBuffer, DWORD dwSize, LPSOCKADDR lpAddrIn,
LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
#endif
/**
* Write to a destination socket
* @param lpBuffer Buffer to send
* @param dwCount Number of bytes to send
* @param lpAddrIn Peer address for UDP - this must be NULL for TCP
* @param dwTimeout Write timeout in milliseconds
* @return number of bytes sent or (-1L) if fail
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, WriteEx
*/
int Write(const LPBYTE lpBuffer, int dwCount, const LPSOCKADDR lpAddrIn = NULL, long dwTimeout = INFINITE);
#ifdef WIN32
/**
* Write to a destination socket (asynchronous mode).
* @param lpBuffer Buffer to send
* @param dwCount Number of bytes to send
* @param lpAddrIn SockAddrIn for UDP - this must be NULL for TCP
* @param lpOverlapped Windows Overlapped structure (required)
* @param lpCompletionRoutine Winsock Completion routine (required)
* @return number of bytes read, overlapped operation is pending or (-1L) if fail
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, Write, IOControl, GetTransferOverlappedResult
*/
DWORD WriteEx(const LPBYTE lpBuffer, DWORD dwCount, const LPSOCKADDR lpAddrIn,
LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
#endif
#ifdef WIN32
/**
* Control the mode of a socket (asynchronous mode)
* @param dwIoCode Control code of operation to perform
* @param lpInBuffer Pointer to the input buffer
* @param cbInBuffer Size of the input buffer, in bytes
* @param lpOutBuffer Pointer to the output buffer
* @param cbOutBuffer Size of the output buffer, in bytes
* @param lpcbBytesReturned Pointer to actual number of bytes of output
* @param lpOverlapped Winsock Overlapped structure
* @param lpCompletionRoutine Winsock Completion routine
* @return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error)
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, GetTransferOverlappedResult
*/
bool IOControl(DWORD dwIoCode, LPBYTE lpInBuffer, DWORD cbInBuffer,
LPBYTE lpOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/**
* Get Overlapped result (asynchronous mode)
* @param lpOverlapped Windows Overlapped structure (required)
* @param lpcbTransfer Pointer to get number of bytes transferred
* @param bWait Force wait for overlapped operation to complete
* @param lpdwFlags Optional flags (see MSDN on WSARecv API)
* @sa InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, IOControl
*/
bool GetTransferOverlappedResult(LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, bool bWait = true, LPDWORD lpdwFlags = 0);
#endif
/**
* Initialize Winsock library. This function calls WSAStartup.
* @param wVersion Winsock version use MAKEWORD macro if possible (e.g.: MAKEWORD(2,2))
* @return true if successful
* @sa ReleaseLibrary
*/
static bool InitLibrary(WORD wVersion);
/**
* Release Winsock library
* @return true if successful
* @sa InitLibrary
*/
static bool ReleaseLibrary();
/**
* Wait for a new connection
* @param sock A TCP socket handle. A new socket is return returned.
* @return A new socket when a new client connects
* @sa GetSocket, CreateSocket
*/
static SOCKET WaitForConnection(SOCKET sock);
/**
* Shutdown a connection
* @param sock Socket to shutdown communication
* @return true if successful
*/
static bool ShutdownConnection(SOCKET sock);
/**
* Check if IP address is unicast (network order).
* @param ulAddr IP address (expected valid unicast address)
* @return true if successful
*/
// CSocketHandle - data
protected:
SOCKET m_hSocket; ///< socket handle
};
/** @}*/
#endif //SOCKETHANDLE_H