CSocket

Win32++

CSocket Class

Description

The CSocket class represents a network socket. It encapsualtes many of the Windows Socket SPI fuctions, providing an object-oriented approach to network programming. After StartEvents is called, CSocket monitors the socket and responds automatically to network events. This event monitoring, for example, automatically calls OnReceive when there is data on the socket to be read, and OnAccept when a server should accept a connection from a client.

Users of this class should be aware that functions like OnReceive, OnAccept, etc. are called on a different thread from the one CSocket is instanciated on. The thread for these functions needs to respond quickly to other network events, so it shouldn't be delayed. It also doesn't run a message loop, so it can't be used to create windows. For these reasons it might be best to use PostMessage in response to these functions in a windows environment.

Refer to the network samples for an example of how to use this class to create a TCP client & server, and a UDP client and server.

To compile programs with CSocket, link with ws2_32.lib for Win32/64, and ws2.lib for Windows CE. Windows 95 systems will need to install the "Windows Sockets 2.0 for Windows 95". It's available from:  http://support.microsoft.com/kb/182108/EN-US/

CSocket Members:

Construction

CSocket
CSocket();
Constructs a CSocket object. A CWinException will be thrown if CSocket can't be constructed properly.

Operations

Accept
virtual void Accept(CSocket& rClientSock, struct sockaddr* addr, int* addrlen);
Constructs a CSocket object.
Bind
virtual int Bind(LPCTSTR addr, UINT port);
virtual int Bind(const struct sockaddr* name, int namelen);
Associates a local address with the socket.
Connect
virtual int Connect(LPCTSTR addr, UINT port);
virtual int Connect(const struct sockaddr* name, int namelen);
Establishes a connection to a peer socket.
Create
virtual bool Create( int family, int type, int protocol = IPPROTO_IP);
Creates a socket.
Disconnect
virtual void Disconnect();
Ends any event notification for the socket, shuts the socket down, and removes it from CSocket.
FreeAddrInfo
virtual void FreeAddrInfo( struct addrinfo* ai );
Frees address information that the getaddrinfo function dynamically allocates in its addrinfo structures.
GetAddrInfo
virtual int GetAddrInfo( LPCTSTR nodename, LPCTSTR servname, const struct addrinfo* hints, struct addrinfo** res);
Provides a protocol-independent translation from host name to address.
ioCtlSocket
virtual int ioCtlSocket(long cmd, u_long* argp);
Controls the I/O mode of the socket.
Listen
virtual int Listen(int backlog = SOMAXCONN);
Establishes a socket to listen for incoming connection requests.
Receive
virtual int Receive(char* buf, int len, int flags);
Receives data from the socket.
ReceiveFrom
ReceiveFrom(char* buf, int len, int flags, struct sockaddr* from, int* fromlen);
Receives a datagram and stores the source address.
Send
virtual int Send(LPCTSTR buf, int len, int flags);
Sends data to a connected socket.
SendTo
virtual int SendTo(const char* send, int len, int flags, LPCTSTR addr, UINT port);
virtual int SendTo(const char* buf, int len, int flags, const struct sockaddr* to, int tolen);
Sends data to a specific destination.
StartEvents
virtual void StartEvents();
Starts the thread which produces the notification of network events.
StopEvents
virtual void StopEvents();
Stops the thread which produces the notification of network events.

Attributes

GetLastError
virtual LPCTSTR GetLastError();
Retrieves the calling thread's last-error code value.
GetPeerName
virtual int GetPeerName(struct sockaddr* name, int* namelen);
Gets the address of the peer socket connected to socket.
GetSocket
SOCKET& GetSocket();
Gets the SOCKET associated with this CSocket.
GetSockName
virtual int GetSockName(struct sockaddr* name, int* namelen);
Gets the local name of a socket.
GetSockOpt
virtual int GetSockOpt(int level, int optname, char* optval, int* optlen);
Gets a socket option.
IsIPV6Supported
virtual bool IsIPV6Supported();
Returns TRUE if the operating system supports IP version 6.
SetSockOpt
virtual int SetSockOpt(int level, int optname, const char* optval, int optlen);
Sets a socket option.

Overridables

OnAccept
virtual void OnAccept();
Notifies a listening socket that it can accept pending connection requests by calling Accept.
OnAddressListChange
virtual void OnAddresListChange();
Notifies a socket that there has been a local address list change.
OnConnect
virtual void OnDisconnect();
Notifies a connecting socket that the connection attempt is complete.
OnDisconnect
virtual void OnConnect();
Notifies a socket that the socket connected to it has closed.
OnOutOfBand
virtual void OnOutOfBand();
Notifies a receiving socket that there is out-of-band data to be read on the socket, usually an urgent message.
OnQualityOfService
virtual void OnQualityOfService();
Notifies a socket that there has been a QOS change.
OnReceive
virtual void OnReceive();
Notifies a listening socket that there is data to be retrieved by calling Receive.
OnRoutingChange
virtual void OnRoutingChange();
Notifies a socket that there has been routing interface change.
OnSend
virtual void OnSend();
Notifies a socket that it can send data by calling Send.

Remarks

CSocket's constructor will throw a CWinException if WSAStartup fails or if the WS2_32.dll DLL fails to load. You can catch this exception if you wish to handle this rather unlikely situation gracefully. Note that windows 95 may not have WS2_32.dll.

IP version 6 support

IP version 6 is not supported on all operating systems or all development environments. Keep the following in mind when offering support for IP version 6 in your applications.

  • IPv6 is supported on Windows Vista and above. Windows XP with SP2 provides "experimental" support, which can be enabled by entering "ipv6 install" at a command prompt.
  • IPv6 is not supported by all compilers and development environments. In particular, it is not supported by Dev-C++ or Borland 5.5. A modern Platform SDK needs to be added to Visual Studio 6 for it to support IPv6.
  • The IsIPV6Supported function returns false if either the operating system or the development environment fails to support IPv6.
Network client code

The following code segments are complete programs which demonstrate how to write a simple network client and server.

#include 
#include 
#include "winsock2.h"
#include "../../Win32++/socket.h"

using namespace std;
using namespace Win32xx;


class CClientSocket : public CSocket
{
public:
  CClientSocket() {}
  virtual void OnReceive()
  {
    // This function is called automatically when there is data to receive
    TCHAR str[1024] = {0};
    int i = Receive(str, 1024, 0);

    cout << i << " chars received: " << str << endl;
  }
};

int main()
{
  CClientSocket Client;

  // Create the socket to communicate with the Server
  if (!Client.Create(SOCK_STREAM))
  {
    cout << "Failed to create socket\n" ;
    return 0;
  }

  // Connect to the server
  if (SOCKET_ERROR == Client.Connect(_T("127.0.0.1", 3000)))
  {
    cout << "Failed to connect to server. Was it running?\n";
    return 0;
  }
  cout << "Connected to server.\n";
  cout << "Type data to send, type quit to exit\n";

  // Monitor the client socket for network events, such as data ready to receive
  Client.StartEvents();

  // Send data to the server
  string s;
  for (;;)	// Infinite loop
  {
    getline(cin, s);
    if (s == "quit") break;
    int i = Client.Send(s.c_str(), (int)s.length(), 0);
    cout << "Sending  " << i << " characters\n";
  }

  return 0;
}
Network server code
#include 
#include 
#include "winsock2.h"
#include "../../Win32++/socket.h"

using namespace std;
using namespace Win32xx;


class CServerSocket : public CSocket
{
public:
  CServerSocket() {}
  virtual ~CServerSocket() {}
  virtual void OnReceive()
  {
    // This function is called automatically when there is data to receive
    TCHAR str[1024] = {0};
    int i = Receive(str, 1024, 0);
    cout << i <<" chars received: " << str << endl;
  }
};

int main()
{
  // Create the main server socket.
  // It is used to listen for clients
  CServerSocket Server;
  if (!Server.Create(SOCK_STREAM))
  {
    cout << "Failed to create socket\n" ;
    return 0;
  }

  // Bind the IP address and port# to the main socket
  if (SOCKET_ERROR == Server.Bind(_T("127.0.0.1", 3000)))
  {
    cout << "Failed to bind IP address to socket\n" ;
    return 0;
  }

  // Listen on the socket for clients to connect
  if (SOCKET_ERROR == Server.Listen())
  {
    cout << "Listen on socket failed\n";
    return 0;
  }

  // Create the socket to communicate with the Client
  CServerSocket Client;
  cout << "Waiting for the client to connect\n";
  do
  {
    Server.Accept(Client, NULL, NULL);
  }
  while (SOCKET_ERROR == Client.GetSocket());

  cout << "Client connected\n";

  // Monitor the client socket for network events, such as data ready to receive
  Client.StartEvents();

  // Send data to the client
  cout << "Type data to send, type quit to exit\n";
  string s;
  for (;;)   // infinite loop
  {
    getline(cin, s);
    if (s == "quit") break;
    int i = Client.Send(s.c_str(), (int)s.length(), 0);
    cout << "Sending  " << i << " characters\n";
  }

  return 0;
}

Refer to the Networking ClientDlg and ServerDlg sample for a more comprehensive demonstration of the features of CSocket.

Summary Information

Header file socket.h
Win32/64 support Yes
WinCE support Yes
Library required ws2_32.lib, or ws2.lib for WinCE