Endpoint is a C++ class which uses Berkeley sockets to communicate with hosts via the Internet, through IPv4 or IPv6, using TCP or UDP or raw IP, on Win32 or Unix operating systems. Originally written for developing peer-to-peer applications, the simple philosophy behind Endpoint is of choice and portability and consistency:
Additionally, data is data. It shouldn't matter how it gets there, via IPv4 or IPv6, on a Win32 or Unix platform. The addressing and connection establishment is the tough part, which this class hierarchy tries to address. New protocol family-independent calls are used, nullifying the need to port to IPv6 once IPv6 becomes more widely used.
Also, Endpoint is to be optimized for typical cases, while still retaining desired functionality. Byte counters are an example of this, as is multiple addresses per host. In the future, perhaps multicasting will be transparently available.
For more information, read below or refer to Tips and Tricks or the EndpointAddress documentation. To download, go to file releases or browse the CVS. For a list of programs using Endpoint see the Endpoint end users page.
Endpoint has been compiled and tested successfully on the following operating systems:
Portability is a major goal. Testers welcome.
Currently:
Not implemented (yet):
The one-address constructors interpret the address as local if type specifies a server, remote if client -- and then calls the two-address constructor. The string parameters just create EndpointAddrlists and pass them to the others. Each constructor is implemented as a Create method, the real constructor simply calls this. Notice how address lists as opposed to a single address are passed: if the first one fails, the others are tried; m_local and m_remote are set to the connected EndpointAddresses.
Specifies protocol and client/server, see address.html.
See address.html. For clients, this is the remote address, for servers, this is the local address.
Default service, see above.
Returns the socket pair as a string, for example: "127.0.0.1:8000 <--> 127.0.0.1:3402". The local address is shown first followed by the foreign address. Invalid addresses are shown as "(invalid)".
Returns true if is connected (m_bool member variable). More useful with TCP sockets than UDP sockets. connect() rarely fails with UDP sockets; you'll usually be notified of a UDP port being closed when you try to write to it. If you want to make sure, write a 0-byte packet and abort if it fails. Endpoint doesn't do this for you because that might interfere with the data.
Writes all data in string, looping if necessary. Calls send(). If any of the send() calls returns -1, returns false. This means the remote host closed the connection, and if you try to send more you'll cause a SIGPIPE on Unix.
Return a string of various statistics of the socket usage. You can also call the socket-wide GetBytesRecv(), GetBytesSent(), or application-wide GetAllBytesRecv() and GetAllBytesSent() calls individually.
Error codes and error strings. Check these if !ep (m_bool=false). Defined values for m_error_code are EP_ERROR_NONE, EP_ERROR_SOCKET, EP_ERROR_BIND, EP_ERROR_ACCEPT, EP_ERROR_SETSOCKOPT, EP_ERROR_CONNECT, EP_ERROR_ADDRESS, and the EndpointAddrlist error EP_ERROR_GETADDRINFO. Each code corresponds to the system call where an error occured. m_error_str is a descriptive, human readable string of the error, suitable for printing. If Endpoint attempts to create an EndpointAddrlist and fails, the error will propagate into these variables.
Set the socket descriptor g_raw_sockfd used for raw sockets, to fd. Useful for, on Unix, separating the socket() call (which usually has to run as root) with the rest of the application code.
Initialize the socket library. Necessary on Win32; this function is called upon the first instanciation of an Endpoint object. On other platforms, nothing happens.
Endpoint isn't the only C++ class to utilize TCP/IP sockets, nor does it claim to be the best. Below are other C++ classes whose purpose is the same as or similar to that of Endpoint's, so one can learn from them.
WinSock is missing this function. The implementation from BIND is included in inet_ntop.c. You can link to inet_ntop_ipv4.c if you only want IPv4 and want to save a little space, but in general inet_ntop.c is preferred. Add this file to your project if you get an error LNK2001: unresolved external symbol _inet_ntop.
You need to download the core "Microsoft Platform SDK" which includes this function. Ask Google for where to download this. Copy the files from "include" to your Microsoft Visual Studio "include" directory, overwriting them. The compile should now work.
You need to link with ws2_32.lib, and the object files of endpoint.cpp, address.cpp, and inet_ntop.c. Also link to ws2_32.lib under Project -> Settings -> Link -> General -> Object/library modules.
Unfortunately, no, as the afxsock.h header will conflict with Endpoint. If you created a project with WOSA support, you can fix it by removing #include <afxsock.h> from stdafx.h and replacing AfxSocketInit() with Endpoint::Initialize(). Also, you may have to change the precompiled header option (Project -> Settings -> C++ -> Category=Precompiled Headers) from "Use precompiled header file (.pch" to "Automatic use of precompiled headers" through stdafx.h. Endpoint doesn't include stdafx.h.
Include endpoint.h in stdafx.h, after the normal afx includes.
Yes, provided your version supports it (Windows XP or Windows 2000). You may be able to create raw sockets as normal users.
Jeff Connelly. Comments, questions, and criticism welcome.
Happy hacking!