FS#86 - Rewrite the sockets API

Updated the API documentation of the whole network module
The system headers are no longer included by the sfml-network public headers

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1475 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-03-23 09:39:43 +00:00
parent a09ee0f9e3
commit 9280771665
66 changed files with 3976 additions and 2992 deletions

View file

@ -34,9 +34,10 @@
#include <SFML/Network/Http.hpp>
#include <SFML/Network/IpAddress.hpp>
#include <SFML/Network/Packet.hpp>
#include <SFML/Network/Selector.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/SocketUDP.hpp>
#include <SFML/Network/SocketSelector.hpp>
#include <SFML/Network/TcpListener.hpp>
#include <SFML/Network/TcpSocket.hpp>
#include <SFML/Network/UdpSocket.hpp>
#endif // SFML_NETWORK_HPP

View file

@ -29,7 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/TcpSocket.hpp>
#include <string>
#include <vector>
@ -39,17 +39,16 @@ namespace sf
class IpAddress;
////////////////////////////////////////////////////////////
/// This class provides methods for manipulating the FTP
/// protocol (described in RFC 959).
/// It provides easy access and transfers to remote
/// directories and files on a FTP server
/// \li A FTP client
///
////////////////////////////////////////////////////////////
class SFML_API Ftp : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// Enumeration of transfer modes
/// \brief Enumeration of transfer modes
///
////////////////////////////////////////////////////////////
enum TransferMode
{
@ -59,17 +58,16 @@ public :
};
////////////////////////////////////////////////////////////
/// This class wraps a FTP response, which is basically :
/// - a status code
/// - a message
/// \brief Define a FTP response
///
////////////////////////////////////////////////////////////
class SFML_API Response
{
public :
////////////////////////////////////////////////////////////
/// Enumerate all the valid status codes returned in
/// a FTP response
/// \brief Status codes possibly returned by a FTP response
///
////////////////////////////////////////////////////////////
enum Status
{
@ -134,25 +132,30 @@ public :
};
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// \param code : Response status code
/// \param message : Response message
/// This constructor is used by the FTP client to build
/// the response.
///
/// \param code Response status code
/// \param message Response message
///
////////////////////////////////////////////////////////////
Response(Status code = InvalidResponse, const std::string& message = "");
////////////////////////////////////////////////////////////
/// Convenience function to check if the response status code
/// means a success
/// \brief Check if the status code means a success
///
/// \return True if status is success (code < 400)
/// This function is defined for convenience, it is
/// equivalent to testing if the status code is < 400.
///
/// \return True if the status is a success, false if it is a failure
///
////////////////////////////////////////////////////////////
bool IsOk() const;
////////////////////////////////////////////////////////////
/// Get the response status code
/// \brief Get the status code of the response
///
/// \return Status code
///
@ -160,7 +163,7 @@ public :
Status GetStatus() const;
////////////////////////////////////////////////////////////
/// Get the full message contained in the response
/// \brief Get the full message contained in the response
///
/// \return The response message
///
@ -177,22 +180,23 @@ public :
};
////////////////////////////////////////////////////////////
/// Specialization of FTP response returning a directory
/// \brief Specialization of FTP response returning a directory
///
////////////////////////////////////////////////////////////
class SFML_API DirectoryResponse : public Response
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// \param response : Source response
/// \param response Source response
///
////////////////////////////////////////////////////////////
DirectoryResponse(Response response);
DirectoryResponse(const Response& response);
////////////////////////////////////////////////////////////
/// Get the directory returned in the response
/// \brief Get the directory returned in the response
///
/// \return Directory name
///
@ -209,38 +213,29 @@ public :
////////////////////////////////////////////////////////////
/// Specialization of FTP response returning a filename lisiting
/// \brief Specialization of FTP response returning a
/// filename lisiting
////////////////////////////////////////////////////////////
class SFML_API ListingResponse : public Response
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// \param response : Source response
/// \param data : Data containing the raw listing
/// \param response Source response
/// \param data Data containing the raw listing
///
////////////////////////////////////////////////////////////
ListingResponse(Response response, const std::vector<char>& data);
ListingResponse(const Response& response, const std::vector<char>& data);
////////////////////////////////////////////////////////////
/// Get the number of filenames in the listing
/// \brief Return the array of filenames
///
/// \return Total number of filenames
/// \return Array containing the requested filenames
///
////////////////////////////////////////////////////////////
std::size_t GetCount() const;
////////////////////////////////////////////////////////////
/// Get the Index-th filename in the directory
///
/// \param index : Index of the filename to get
///
/// \return Index-th filename
///
////////////////////////////////////////////////////////////
const std::string& GetFilename(std::size_t index) const;
const std::vector<std::string>& GetFilenames() const;
private :
@ -252,25 +247,52 @@ public :
////////////////////////////////////////////////////////////
/// Destructor -- close the connection with the server
/// \brief Destructor
///
/// Automatically closes the connection with the server if
/// it is still opened.
///
////////////////////////////////////////////////////////////
~Ftp();
////////////////////////////////////////////////////////////
/// Connect to the specified FTP server
/// \brief Connect to the specified FTP server
///
/// \param server : FTP server to connect to
/// \param port : Port used for connection (21 by default, standard FTP port)
/// \param timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
/// The port has a default value of 21, which is the standard
/// port used by the FTP protocol. You shouldn't use a different
/// value, unless you really know what you do.
/// This function tries to connect to the server so it may take
/// a while to complete, especially if the server is not
/// reachable. To avoid blocking your application for too long,
/// you can use a timeout. The default value, 0, means that the
/// system timeout will be used (which is usually pretty long).
///
/// \param server Name or address of the FTP server to connect to
/// \param port Port used for the connection
/// \param timeout Maximum time to wait, in seconds
///
/// \return Server response to the request
///
/// \see Disconnect
///
////////////////////////////////////////////////////////////
Response Connect(const IpAddress& server, unsigned short port = 21, float timeout = 0.f);
////////////////////////////////////////////////////////////
/// Log in using anonymous account
/// \brief Close the connection with the server
///
/// \return Server response to the request
///
/// \see Connect
///
////////////////////////////////////////////////////////////
Response Disconnect();
////////////////////////////////////////////////////////////
/// \brief Log in using an anonymous account
///
/// Logging in is mandatory after connecting to the server.
/// Users that are not logged in cannot perform any operation.
///
/// \return Server response to the request
///
@ -278,10 +300,13 @@ public :
Response Login();
////////////////////////////////////////////////////////////
/// Log in using a username and a password
/// \brief Log in using a username and a password
///
/// \param name : User name
/// \param password : Password
/// Logging in is mandatory after connecting to the server.
/// Users that are not logged in cannot perform any operation.
///
/// \param name User name
/// \param password Password
///
/// \return Server response to the request
///
@ -289,15 +314,10 @@ public :
Response Login(const std::string& name, const std::string& password);
////////////////////////////////////////////////////////////
/// Close the connection with FTP server
/// \brief Send a null command to keep the connection alive
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Disconnect();
////////////////////////////////////////////////////////////
/// Send a null command just to prevent from being disconnected
/// This command is useful because the server may close the
/// connection automatically if no command is sent.
///
/// \return Server response to the request
///
@ -305,31 +325,46 @@ public :
Response KeepAlive();
////////////////////////////////////////////////////////////
/// Get the current working directory
/// \brief Get the current working directory
///
/// The working directory is the root path for subsequent
/// operations involving directories and/or filenames.
///
/// \return Server response to the request
///
/// \see GetDirectoryListing, ChangeDirectory, ParentDirectory
///
////////////////////////////////////////////////////////////
DirectoryResponse GetWorkingDirectory();
////////////////////////////////////////////////////////////
/// Get the contents of the given directory
/// (subdirectories and files)
/// \brief Get the contents of the given directory
///
/// \param directory : Directory to list ("" by default, the current one)
/// This function retrieves the sub-directories and files
/// contained in the given directory. It is not recursive.
/// The \a directory parameter is relative to the current
/// working directory.
///
/// \param directory Directory to list
///
/// \return Server response to the request
///
/// \see GetWorkingDirectory, ChangeDirectory, ParentDirectory
///
////////////////////////////////////////////////////////////
ListingResponse GetDirectoryListing(const std::string& directory = "");
////////////////////////////////////////////////////////////
/// Change the current working directory
/// \brief Change the current working directory
///
/// \param directory : New directory, relative to the current one
/// The new directory must be relative to the current one.
///
/// \param directory New working directory
///
/// \return Server response to the request
///
/// \see GetWorkingDirectory, GetDirectoryListing, ParentDirectory
///
////////////////////////////////////////////////////////////
Response ChangeDirectory(const std::string& directory);
@ -338,81 +373,127 @@ public :
///
/// \return Server response to the request
///
/// \see GetWorkingDirectory, GetDirectoryListing, ChangeDirectory
///
////////////////////////////////////////////////////////////
Response ParentDirectory();
////////////////////////////////////////////////////////////
/// Create a new directory
/// \brief Create a new directory
///
/// \param name : Name of the directory to create
/// The new directory is created as a child of the current
/// working directory.
///
/// \param name Name of the directory to create
///
/// \return Server response to the request
///
/// \see DeleteDirectory
///
////////////////////////////////////////////////////////////
Response MakeDirectory(const std::string& name);
Response CreateDirectory(const std::string& name);
////////////////////////////////////////////////////////////
/// Remove an existing directory
/// \brief Remove an existing directory
///
/// \param Name : Name of the directory to remove
/// The directory to remove must be relative to the
/// current working directory.
/// Use this function with caution, the directory will
/// be removed permanently!
///
/// \param Name Name of the directory to remove
///
/// \return Server response to the request
///
/// \see CreateDirectory
///
////////////////////////////////////////////////////////////
Response DeleteDirectory(const std::string& name);
////////////////////////////////////////////////////////////
/// Rename a file
/// \brief Rename an existing file
///
/// \param file : File to rename
/// \param newName : New name
/// The filenames must be relative to the current working
/// directory.
///
/// \param file File to rename
/// \param newName New name of the file
///
/// \return Server response to the request
///
/// \see DeleteFile
///
////////////////////////////////////////////////////////////
Response RenameFile(const std::string& file, const std::string& newName);
////////////////////////////////////////////////////////////
/// Remove an existing file
/// \brief Remove an existing file
///
/// \param name : File to remove
/// The file name must be relative to the current working
/// directory.
/// Use this function with caution, the file will be
/// removed permanently!
///
/// \param name File to remove
///
/// \return Server response to the request
///
/// \see RenameFile
///
////////////////////////////////////////////////////////////
Response DeleteFile(const std::string& name);
////////////////////////////////////////////////////////////
/// Download a file from the server
/// \brief Download a file from the server
///
/// \param distantFile : Path of the distant file to download
/// \param destPath : Where to put to file on the local computer
/// \param mode : Transfer mode
/// The filename of the distant file is relative to the
/// current working directory of the server, and the local
/// destination path is relative to the current directory
/// of your application.
/// If you want to watch the progress (to update a progress bar
/// for example) or have the ability to stop or pause the download,
/// you can use the fourth parameter to pass your progress handler.
///
/// \param remoteFile Filename of the distant file to download
/// \param localPath Where to put to file on the local computer
/// \param mode Transfer mode
/// \param handler Object that will be notified of the download progress
///
/// \return Server response to the request
///
/// \see Upload
///
////////////////////////////////////////////////////////////
Response Download(const std::string& distantFile, const std::string& destPath, TransferMode mode = Binary);
Response Download(const std::string& remoteFile, const std::string& localPath, TransferMode mode = Binary);
////////////////////////////////////////////////////////////
/// Upload a file to the server
/// \brief Upload a file to the server
///
/// \param localFile : Path of the local file to upload
/// \param destPath : Where to put to file on the server
/// \param mode : Transfer mode
/// The name of the local file is relative to the current
/// working directory of your application, and the
/// remote path is relative to the current directory of the
/// FTP server.
/// If you want to watch the progress (to update a progress bar
/// for example) or have the ability to stop or pause the upload,
/// you can use the fourth parameter to pass your progress handler.
///
/// \param localFile Path of the local file to upload
/// \param remotePath Where to put to file on the server
/// \param mode Transfer mode
/// \param handler Object that will be notified of the upload progress
///
/// \return Server response to the request
///
////////////////////////////////////////////////////////////
Response Upload(const std::string& localFile, const std::string& destPath, TransferMode mode = Binary);
Response Upload(const std::string& localFile, const std::string& remotePath, TransferMode mode = Binary);
private :
////////////////////////////////////////////////////////////
/// Send a command to the FTP server
/// \brief Send a command to the FTP server
///
/// \param command : Command to send
/// \param parameter : Command parameter
/// \param command Command to send
/// \param parameter Command parameter
///
/// \return Server response to the request
///
@ -420,8 +501,10 @@ private :
Response SendCommand(const std::string& command, const std::string& parameter = "");
////////////////////////////////////////////////////////////
/// Receive a response from the server
/// (usually after a command has been sent)
/// \brief Receive a response from the server
///
/// This function must be called after each call to
/// SendCommand that expects a response.
///
/// \return Server response to the request
///
@ -429,8 +512,9 @@ private :
Response GetResponse();
////////////////////////////////////////////////////////////
/// Utility class for exchanging datas with the server
/// on the data channel
/// \brief Utility class for exchanging datas with the server
/// on the data channel
///
////////////////////////////////////////////////////////////
class DataChannel;
@ -439,10 +523,72 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTCP myCommandSocket; ///< Socket holding the control connection with the server
TcpSocket myCommandSocket; ///< Socket holding the control connection with the server
};
} // namespace sf
#endif // SFML_FTP_HPP
////////////////////////////////////////////////////////////
/// \class sf::Ftp
///
/// sf::Ftp is a very simple FTP client that allows you
/// to communicate with a FTP server. The FTP protocol allows
/// you to manipulate a remote file system (list files,
/// upload, download, create, remove, ...).
///
/// Using the FTP client consists of 4 parts:
/// \li Connecting to the FTP server
/// \li Logging in (either as a registered user or anonymously)
/// \li Sending commands to the server
/// \li Disconnecting (this part can be done implicitely by the destructor)
///
/// Every command returns a FTP response, which contains the
/// status code as well as a message from the server. Some
/// commands such as GetWorkingDirectory and GetDirectoryListing
/// return additional data, and use a class derived from
/// sf::Ftp::Response to provide this data.
///
/// All commands, especially Upload and Download, may take some
/// time to complete. This is important to know if you don't want
/// to block your application while the server is completing
/// the task.
///
/// Usage example:
/// \code
/// // Create a new FTP client
/// sf::Ftp ftp;
///
/// // Connect to the server
/// sf::Ftp::Response response = ftp.Connect("ftp://ftp.myserver.com");
/// if (response.IsOk())
/// std::cout << "Connected" << std::endl;
///
/// // Log in
/// response = ftp.Login("laurent", "dF6Zm89D");
/// if (response.IsOk())
/// std::cout << "Logged in" << std::endl;
///
/// // Print the working directory
/// sf::Ftp::DirectoryResponse directory = ftp.GetWorkingDirectory();
/// if (directory.IsOk())
/// std::cout << "Working directory: " << directory.GetDirectory() << std::endl;
///
/// // Create a new directory
/// response = ftp.CreateDirectory("files");
/// if (response.IsOk())
/// std::cout << "Created new directory" << std::endl;
///
/// // Upload a file to this new directory
/// response = ftp.Upload("local-path/file.txt", "files", sf::Ftp::Ascii);
/// if (response.IsOk())
/// std::cout << "File uploaded" << std::endl;
///
/// // Disconnect from the server (optional)
/// ftp.Disconnect();
/// \endcode
///
////////////////////////////////////////////////////////////

View file

@ -30,7 +30,7 @@
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Network/IpAddress.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/TcpSocket.hpp>
#include <map>
#include <string>
@ -38,25 +38,24 @@
namespace sf
{
////////////////////////////////////////////////////////////
/// This class provides methods for manipulating the HTTP
/// protocol (described in RFC 1945).
/// It can connect to a website, get its files, send requests, etc.
/// \brief A HTTP client
///
////////////////////////////////////////////////////////////
class SFML_API Http : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// This class wraps an HTTP request, which is basically :
/// - a header with a method, a target URI, and a set of field/value pairs
/// - an optional body (for POST requests)
/// \brief Define a HTTP request
///
////////////////////////////////////////////////////////////
class SFML_API Request
{
public :
////////////////////////////////////////////////////////////
/// Enumerate the available HTTP methods for a request
/// \brief Enumerate the available HTTP methods for a request
///
////////////////////////////////////////////////////////////
enum Method
{
@ -66,58 +65,76 @@ public :
};
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// \param method : Method to use for the request
/// \param URI : Target URI
/// \param body : Content of the request's body
/// This constructor creates a GET request, with the root
/// URI ("/") and an empty body.
///
/// \param uri Target URI
/// \param method Method to use for the request
/// \param body Content of the request's body
///
////////////////////////////////////////////////////////////
Request(Method method = Get, const std::string& URI = "/", const std::string& body = "");
Request(const std::string& uri = "/", Method method = Get, const std::string& body = "");
////////////////////////////////////////////////////////////
/// Set the value of a field; the field is added if it doesn't exist
/// \brief Set the value of a field
///
/// \param field : Name of the field to set (case-insensitive)
/// \param value : Value of the field
/// The field is created if it doesn't exist. The name of
/// the field is case insensitive.
/// By default, a request doesn't contain any field (but the
/// mandatory fields are added later by the HTTP client when
/// sending the request).
///
/// \param field Name of the field to set
/// \param value Value of the field
///
////////////////////////////////////////////////////////////
void SetField(const std::string& field, const std::string& value);
////////////////////////////////////////////////////////////
/// Set the request method.
/// This parameter is Http::Request::Get by default
/// \brief Set the request method
///
/// \param method : Method to use for the request
/// See the Method enumeration for a complete list of all
/// the availale methods.
/// The method is Http::Request::Get by default.
///
/// \param method Method to use for the request
///
////////////////////////////////////////////////////////////
void SetMethod(Method method);
////////////////////////////////////////////////////////////
/// Set the target URI of the request.
/// This parameter is "/" by default
/// \brief Set the requested URI
///
/// \param URI : URI to request, local to the host
/// The URI is the resource (usually a web page or a file)
/// that you want to get or post.
/// The URI is "/" (the root page) by default.
///
/// \param uri URI to request, relative to the host
///
////////////////////////////////////////////////////////////
void SetURI(const std::string& URI);
void SetUri(const std::string& uri);
////////////////////////////////////////////////////////////
/// Set the HTTP version of the request.
/// This parameter is 1.0 by default
/// \brief Set the HTTP version fo the request
///
/// \param major : Major version number
/// \param minor : Minor version number
/// The HTTP version is 1.0 by default.
///
/// \param major Major HTTP version number
/// \param minor Minor HTTP version number
///
////////////////////////////////////////////////////////////
void SetHttpVersion(unsigned int major, unsigned int minor);
////////////////////////////////////////////////////////////
/// Set the body of the request. This parameter is optional and
/// makes sense only for POST requests.
/// This parameter is empty by default
/// \brief Set the body of the request
///
/// \param body : Content of the request body
/// The body of a request is optional and only makes sense
/// for POST requests. It is ignored for all other methods.
/// The body is empty by default.
///
/// \param body Content of the body
///
////////////////////////////////////////////////////////////
void SetBody(const std::string& body);
@ -127,19 +144,24 @@ public :
friend class Http;
////////////////////////////////////////////////////////////
/// Get the string representation of the request header
/// \brief Prepare the final request to send to the server
///
/// \return String containing the request
/// This is used internally by Http before sending the
/// request to the web server.
///
/// \return String containing the request, ready to be sent
///
////////////////////////////////////////////////////////////
std::string ToString() const;
std::string Prepare() const;
////////////////////////////////////////////////////////////
/// Check if the given field has been defined
/// \brief Check if the request defines a field
///
/// \param field : Name of the field to check (case-insensitive)
/// This function uses case-insensitive comparisons.
///
/// \return True if the field exists
/// \param field Name of the field to test
///
/// \return True if the field exists, false otherwise
///
////////////////////////////////////////////////////////////
bool HasField(const std::string& field) const;
@ -152,7 +174,7 @@ public :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
FieldTable myFields; ///< Fields of the header
FieldTable myFields; ///< Fields of the header associated to their value
Method myMethod; ///< Method to use for the request
std::string myURI; ///< Target URI of the request
unsigned int myMajorVersion; ///< Major HTTP version
@ -161,17 +183,16 @@ public :
};
////////////////////////////////////////////////////////////
/// This class wraps an HTTP response, which is basically :
/// - a header with a status code and a set of field/value pairs
/// - a body (the content of the requested resource)
/// \brief Define a HTTP response
///
////////////////////////////////////////////////////////////
class SFML_API Response
{
public :
////////////////////////////////////////////////////////////
/// Enumerate all the valid status codes returned in
/// a HTTP response
/// \brief Enumerate all the valid status codes for a response
///
////////////////////////////////////////////////////////////
enum Status
{
@ -210,15 +231,21 @@ public :
};
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// Constructs an empty response.
///
////////////////////////////////////////////////////////////
Response();
////////////////////////////////////////////////////////////
/// Get the value of a field
/// \brief Get the value of a field
///
/// \param field : Name of the field to get (case-insensitive)
/// If the field \a field is not found in the response header,
/// the empty string is returned. This function uses
/// case-insensitive comparisons.
///
/// \param field Name of the field to get
///
/// \return Value of the field, or empty string if not found
///
@ -226,35 +253,46 @@ public :
const std::string& GetField(const std::string& field) const;
////////////////////////////////////////////////////////////
/// Get the header's status code
/// \brief Get the response status code
///
/// \return Header's status code
/// The status code should be the first thing to be checked
/// after receiving a response, it defines whether it is a
/// success, a failure or anything else (see the Status
/// enumeration).
///
/// \return Status code of the response
///
////////////////////////////////////////////////////////////
Status GetStatus() const;
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
/// \brief Get the major HTTP version number of the response
///
/// \return Major version number
/// \return Major HTTP version number
///
/// \see GetMinorHttpVersion
///
////////////////////////////////////////////////////////////
unsigned int GetMajorHttpVersion() const;
////////////////////////////////////////////////////////////
/// Get the major HTTP version number of the response
/// \brief Get the minor HTTP version number of the response
///
/// \return Major version number
/// \return Minor HTTP version number
///
/// \see GetMajorHttpVersion
///
////////////////////////////////////////////////////////////
unsigned int GetMinorHttpVersion() const;
////////////////////////////////////////////////////////////
/// Get the body of the response. The body can contain :
/// - the requested page (for GET requests)
/// - a response from the server (for POST requests)
/// - nothing (for HEAD requests)
/// - an error message (in case of an error)
/// \brief Get the body of the response
///
/// The body of a response may contain:
/// \li the requested page (for GET requests)
/// \li a response from the server (for POST requests)
/// \li nothing (for HEAD requests)
/// \li an error message (in case of an error)
///
/// \return The response body
///
@ -266,12 +304,15 @@ public :
friend class Http;
////////////////////////////////////////////////////////////
/// Construct the header from a response string
/// \brief Construct the header from a response string
///
/// \param data : Content of the response's header to parse
/// This function is used by Http to build the response
/// of a request.
///
/// \param data Content of the response to parse
///
////////////////////////////////////////////////////////////
void FromString(const std::string& data);
void Parse(const std::string& data);
////////////////////////////////////////////////////////////
// Types
@ -289,39 +330,58 @@ public :
};
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
Http();
////////////////////////////////////////////////////////////
/// Construct the Http instance with the target host
/// \brief Construct the HTTP client with the target host
///
/// \param host : Web server to connect to
/// \param port : Port to use for connection (0 by default -- use the standard port of the protocol used)
/// This is equivalent to calling SetHost(host, port).
/// The port has a default value of 0, which means that the
/// HTTP client will use the right port according to the
/// protocol used (80 for HTTP, 443 for HTTPS). You should
/// leave it like this unless you really need a port other
/// than the standard one, or use an unknown protocol.
///
/// \param host Web server to connect to
/// \param port Port to use for connection
///
////////////////////////////////////////////////////////////
Http(const std::string& host, unsigned short port = 0);
////////////////////////////////////////////////////////////
/// Set the target host
/// \brief Set the target host
///
/// \param host : Web server to connect to
/// \param port : Port to use for connection (0 by default -- use the standard port of the protocol used)
/// This function just stores the host address and port, it
/// doesn't actually connect to it until you send a request.
/// The port has a default value of 0, which means that the
/// HTTP client will use the right port according to the
/// protocol used (80 for HTTP, 443 for HTTPS). You should
/// leave it like this unless you really need a port other
/// than the standard one, or use an unknown protocol.
///
/// \param host Web server to connect to
/// \param port Port to use for connection
///
////////////////////////////////////////////////////////////
void SetHost(const std::string& host, unsigned short port = 0);
////////////////////////////////////////////////////////////
/// Send a HTTP request and return the server's response.
/// You must be connected to a host before sending requests.
/// Any missing mandatory header field will be added with an appropriate value.
/// Warning : this function waits for the server's response and may
/// not return instantly; use a thread if you don't want to block your
/// application.
/// \brief Send a HTTP request and return the server's response.
///
/// \param request : Request to send
/// \param timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
/// You must have a valid host before sending a request (see SetHost).
/// Any missing mandatory header field in the request will be added
/// with an appropriate value.
/// Warning: this function waits for the server's response and may
/// not return instantly; use a thread if you don't want to block your
/// application, or use a timeout to limit the time to wait. A value
/// of 0 means that the client will use the system defaut timeout
/// (which is usually pretty long).
///
/// \param request Request to send
/// \param timeout Maximum time to wait, in seconds
///
/// \return Server's response
///
@ -333,7 +393,7 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTCP myConnection; ///< Connection to the host
TcpSocket myConnection; ///< Connection to the host
IpAddress myHost; ///< Web host address
std::string myHostName; ///< Web host name
unsigned short myPort; ///< Port used for connection with host
@ -343,3 +403,62 @@ private :
#endif // SFML_HTTP_HPP
////////////////////////////////////////////////////////////
/// \class sf::Http
///
/// sf::Http is a very simple HTTP client that allows you
/// to communicate with a web server. You can retrieve
/// web pages, send data to an interactive resource,
/// download a remote file, etc.
///
/// The HTTP client is split into 3 classes:
/// \li sf::Http::Request
/// \li sf::Http::Response
/// \li sf::Http
///
/// sf::Http::Request builds the request that will be
/// sent to the server. A request is made of:
/// \li a method (what you want to do)
/// \li a target URI (usually the name of the web page or file)
/// \li one or more header fields (options that you can pass to the server)
/// \li an optional body (for POST requests)
///
/// sf::Http::Response parse the response from the web server
/// and provides getters to read them. The response contains:
/// \li a status code
/// \li header fields (that may be answers to the ones that you requested)
/// \li a body, which contains the contents of the requested resource
///
/// sf::Http provides a simple function, SendRequest, to send a
/// sf::Http::Request and return the corresponding sf::Http::Response
/// from the server.
///
/// Usage example:
/// \code
/// // Create a new HTTP client
/// sf::Http http;
///
/// // We'll work on http://www.sfml-dev.org
/// http.SetHost("http://www.sfml-dev.org");
///
/// // Prepare a request to get the 'features.php' page
/// sf::Http::Request request("features.php");
///
/// // Send the request
/// sf::Http::Response response = http.SendRequest(request);
///
/// // Check the status code and display the result
/// sf::Http::Response::Status status = response.GetStatus();
/// if (status == sf::Http::Response::Ok)
/// {
/// std::cout << response.GetBody() << std::endl;
/// }
/// else
/// {
/// std::cout << "Error " << status << std::endl;
/// }
/// \endcode
///
////////////////////////////////////////////////////////////

View file

@ -105,7 +105,7 @@ public :
/// \see ToInteger
///
////////////////////////////////////////////////////////////
IpAddress(Uint32 address);
explicit IpAddress(Uint32 address);
////////////////////////////////////////////////////////////
/// \brief Get a string representation of the address

View file

@ -36,77 +36,133 @@
namespace sf
{
class String;
class TcpSocket;
class UdpSocket;
////////////////////////////////////////////////////////////
/// Packet wraps data to send / to receive through the network
/// \brief Utility class to build blocks of data to transfer
/// over the network
///
////////////////////////////////////////////////////////////
class SFML_API Packet
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
/// \brief Default constructor
///
/// Creates an empty packet.
///
////////////////////////////////////////////////////////////
Packet();
////////////////////////////////////////////////////////////
/// Virtual destructor
/// \brief Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Packet();
////////////////////////////////////////////////////////////
/// Append data to the end of the packet
/// \brief Append data to the end of the packet
///
/// \param data : Pointer to the bytes to append
/// \param sizeInBytes : Number of bytes to append
/// \param data Pointer to the sequence of bytes to append
/// \param sizeInBytes Number of bytes to append
///
/// \see Clear
///
////////////////////////////////////////////////////////////
void Append(const void* data, std::size_t sizeInBytes);
////////////////////////////////////////////////////////////
/// Clear the packet data
/// \brief Clear the packet
///
/// After calling Clear, the packet is empty.
///
/// \see Append
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Get a pointer to the data contained in the packet
/// Warning : the returned pointer may be invalid after you
/// append data to the packet
/// \brief Get a pointer to the data contained in the packet
///
/// Warning: the returned pointer may become invalid after
/// you append data to the packet, therefore it should never
/// be stored.
/// The return pointer is NULL if the packet is empty.
///
/// \return Pointer to the data
///
/// \see GetDataSize
///
////////////////////////////////////////////////////////////
const char* GetData() const;
////////////////////////////////////////////////////////////
/// Get the size of the data contained in the packet
/// \brief Get the size of the data contained in the packet
///
/// This function returns the number of bytes pointed to by
/// what GetData returns.
///
/// \return Data size, in bytes
///
/// \see GetData
///
////////////////////////////////////////////////////////////
std::size_t GetDataSize() const;
////////////////////////////////////////////////////////////
/// Tell if the reading position has reached the end of the packet
/// \brief Tell if the reading position has reached the
/// end of the packet
///
/// \return True if all data have been read into the packet
/// This function is useful to know if there is some data
/// left to be read, without actually reading it.
///
/// \return True if all data was read, false otherwise
///
/// \see operator bool
///
////////////////////////////////////////////////////////////
bool EndOfPacket() const;
////////////////////////////////////////////////////////////
/// Return the validity of packet
/// \brief Test the validity of the packet, for reading
///
/// This operator allows to test the packet as a boolean
/// variable, to check if a reading operation was successful.
///
/// A packet will be in an invalid state if it has no more
/// data to read.
///
/// This behaviour is the same as standard C++ streams.
///
/// Usage example:
/// \begincode
/// float x;
/// packet >> x;
/// if (packet)
/// {
/// // ok, x was extracted successfully
/// }
///
/// // -- or --
///
/// float x;
/// if (packet >> x)
/// {
/// // ok, x was extracted successfully
/// }
/// \endcode
///
/// \return True if last data extraction from packet was successful
///
/// \see EndOfPacket
///
////////////////////////////////////////////////////////////
operator bool() const;
////////////////////////////////////////////////////////////
/// Operator >> overloads to extract data from the packet
/// Overloads of operator >> to read data from the packet
///
////////////////////////////////////////////////////////////
Packet& operator >>(bool& data);
@ -125,7 +181,7 @@ public :
Packet& operator >>(String& data);
////////////////////////////////////////////////////////////
/// Operator << overloads to put data into the packet
/// Overloads of operator << to write data into the packet
///
////////////////////////////////////////////////////////////
Packet& operator <<(bool data);
@ -145,37 +201,57 @@ public :
private :
friend class SocketTCP;
friend class SocketUDP;
friend class TcpSocket;
friend class UdpSocket;
////////////////////////////////////////////////////////////
/// Check if the packet can extract a given size of bytes
/// \brief Check if the packet can extract a given number of bytes
///
/// \param size : Size to check
/// This function updates accordingly the state of the packet.
///
/// \return True if Size bytes can be read from the packet's data
/// \param size Size to check
///
/// \return True if \a size bytes can be read from the packet
///
////////////////////////////////////////////////////////////
bool CheckSize(std::size_t size);
////////////////////////////////////////////////////////////
/// Called before the packet is sent to the network
/// \brief Called before the packet is sent over the network
///
/// \param dataSize : Variable to fill with the size of data to send
/// This function can be defined by derived classes to
/// transform the data before it is sent; this can be
/// used for compression, encryption, etc.
/// The function must return a pointer to the modified data,
/// as well as the number of bytes pointed.
/// The default implementation provides the packet's data
/// without transforming it.
///
/// \param size Variable to fill with the size of data to send
///
/// \return Pointer to the array of bytes to send
///
/// \see OnReceive
///
////////////////////////////////////////////////////////////
virtual const char* OnSend(std::size_t& dataSize);
virtual const char* OnSend(std::size_t& size);
////////////////////////////////////////////////////////////
/// Called after the packet has been received from the network
/// \brief Called after the packet is received over the network
///
/// \param data : Pointer to the array of received bytes
/// \param dataSize : Size of the array of bytes
/// This function can be defined by derived classes to
/// transform the data after it is received; this can be
/// used for uncompression, decryption, etc.
/// The function receives a pointer to the received data,
/// and must fill the packet with the transformed bytes.
/// The default implementation fills the packet directly
/// without transforming the data.
///
/// \param data Pointer to the received bytes
/// \param size Number of bytes
///
////////////////////////////////////////////////////////////
virtual void OnReceive(const char* data, std::size_t dataSize);
virtual void OnReceive(const char* data, std::size_t size);
////////////////////////////////////////////////////////////
// Member data
@ -189,3 +265,122 @@ private :
#endif // SFML_PACKET_HPP
////////////////////////////////////////////////////////////
/// \class sf::Packet
///
/// Packets provide a safe and easy way to serialize data,
/// in order to send it over the network using sockets
/// (sf::TcpSocket, sf::UdpSocket).
///
/// Packets solve 2 fundamental problems that arise when
/// transfering data over the network:
/// \li data is interpreted correctly according to the endianness
/// \li the bounds of the packet are preserved (one send == one receive)
///
/// The sf::Packet class provides both input and output modes.
/// It is designed to follow the behaviour of standard C++ streams,
/// using operators >> and << to extract and insert data.
///
/// It is recommended to use only fixed-size types (like sf::Int32, etc.),
/// to avoid possible differences between the sender and the receiver.
/// Indeed, the native C++ types may have different sizes on two platforms
/// and your data may be corrupted if that happens.
///
/// Usage example:
/// \begincode
/// sf::Uint32 x = 24;
/// std::string s = "hello";
/// double d = 5.89;
///
/// // Group the variables to send into a packet
/// sf::Packet packet;
/// packet << x << s << d;
///
/// // Send it over the network (socket is a valid sf::TcpSocket)
/// socket.Send(packet);
///
/// -----------------------------------------------------------------
///
/// // Receive the packet at the other end
/// sf::Packet packet;
/// socket.Receive(packet);
///
/// // Extract the variables contained in the packet
/// sf::Uint32 x;
/// std::string s;
/// double d;
/// if (packet >> x >> s >> d)
/// {
/// // Data extracted successfully...
/// }
/// \endcode
///
/// Packets have built-in operator >> and << overloads for
/// standard types:
/// \li bool
/// \li fixed-size integer types (sf::Int8/16/32, sf::Uint8/16/32)
/// \li floating point numbers (float, double)
/// \li string types (char*, wchar_t*, std::string, std::wstring, sf::String)
///
/// Like standard streams, it is also possible to define your own
/// overloads of operators >> and << in order to handle your
/// custom types.
///
/// \begincode
/// struct MyStruct
/// {
/// float number;
/// sf::Int8 integer;
/// std::string str;
/// };
///
/// sf::Packet& operator <<(sf::Packet& packet, const MyStruct& m)
/// {
/// return packet << m.number << m.integer << m.str;
/// }
///
/// sf::Packet& operator >>(sf::Packet& packet, MyStruct& m)
/// {
/// return packet >> m.number >> m.integer >> m.str;
/// }
/// \endcode
///
/// Packets also provide an extra feature that allows to apply
/// custom transformations to the data before it is sent,
/// and after it is received. This is typically used to
/// handle automatic compression or encryption of the data.
/// This is achieved by inheriting from sf::Packet, and overriding
/// the OnSend and OnReceive functions.
///
/// Here is an example:
/// \begincode
/// class ZipPacket : public sf::Packet
/// {
/// virtual const char* OnSend(std::size_t& size)
/// {
/// const char* srcData = GetData();
/// std::size_t srcSize = GetDataSize();
///
/// return MySuperZipFunction(srcData, srcSize, &size);
/// }
///
/// virtual void OnReceive(const char* data, std::size_t size)
/// {
/// std::size_t dstSize;
/// const char* dstData = MySuperUnzipFunction(data, size, &dstSize);
///
/// Append(dstData, dstSize);
/// }
/// };
///
/// // Use like regular packets:
/// ZipPacket packet;
/// packet << x << s << d;
/// ...
/// \endcode
///
/// \see sf::TcpSocket, sf::UdpSocket
///
////////////////////////////////////////////////////////////

View file

@ -1,116 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SELECTOR_HPP
#define SFML_SELECTOR_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketUDP.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <SFML/Network/SelectorBase.hpp>
#include <map>
namespace sf
{
////////////////////////////////////////////////////////////
/// Selector allow reading from multiple sockets
/// without blocking. It's a kind of multiplexer
////////////////////////////////////////////////////////////
template <typename Type>
class Selector : private SelectorBase
{
public :
////////////////////////////////////////////////////////////
/// Add a socket to watch
///
/// \param socket : Socket to add
///
////////////////////////////////////////////////////////////
void Add(Type socket);
////////////////////////////////////////////////////////////
/// Remove a socket
///
/// \param socket : Socket to remove
///
////////////////////////////////////////////////////////////
void Remove(Type socket);
////////////////////////////////////////////////////////////
/// Remove all sockets
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
///
/// \param timeout : Timeout, in seconds (0 by default : no timeout)
///
/// \return Number of sockets ready to be read
///
////////////////////////////////////////////////////////////
unsigned int Wait(float timeout = 0.f);
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
///
/// \param index : Index of the socket to get
///
/// \return The index-th socket
///
////////////////////////////////////////////////////////////
Type GetSocketReady(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////
typedef std::map<SocketHelper::SocketType, Type> SocketTable;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketTable mySockets; ///< Table matching the SFML socket instances with their low-level handles
};
#include <SFML/Network/Selector.inl>
// Let's define the two only valid types of Selector
typedef Selector<SocketUDP> SelectorUDP;
typedef Selector<SocketTCP> SelectorTCP;
} // namespace sf
#endif // SFML_SELECTOR_HPP

View file

@ -1,97 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Add a socket to watch
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Add(Type socket)
{
if (socket.IsValid())
{
SelectorBase::Add(socket.mySocket);
mySockets[socket.mySocket] = socket;
}
}
////////////////////////////////////////////////////////////
/// Remove a socket
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Remove(Type socket)
{
typename SocketTable::iterator it = mySockets.find(socket.mySocket);
if (it != mySockets.end())
{
SelectorBase::Remove(socket.mySocket);
mySockets.erase(it);
}
}
////////////////////////////////////////////////////////////
/// Remove all sockets
////////////////////////////////////////////////////////////
template <typename Type>
void Selector<Type>::Clear()
{
SelectorBase::Clear();
mySockets.clear();
}
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
////////////////////////////////////////////////////////////
template <typename Type>
unsigned int Selector<Type>::Wait(float timeout)
{
// No socket in the selector : return 0
if (mySockets.empty())
return 0;
return SelectorBase::Wait(timeout);
}
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
////////////////////////////////////////////////////////////
template <typename Type>
Type Selector<Type>::GetSocketReady(unsigned int index) const
{
SocketHelper::SocketType socket = SelectorBase::GetSocketReady(index);
typename SocketTable::const_iterator it = mySockets.find(socket);
if (it != mySockets.end())
return it->second;
else
return Type(socket);
}

View file

@ -1,112 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SELECTORBASE_HPP
#define SFML_SELECTORBASE_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#include <SFML/Network/SocketHelper.hpp>
#include <map>
namespace sf
{
////////////////////////////////////////////////////////////
/// Private base class for selectors.
/// As Selector is a template class, this base is needed so that
/// every system call get compiled in SFML (not inlined)
////////////////////////////////////////////////////////////
class SFML_API SelectorBase
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SelectorBase();
////////////////////////////////////////////////////////////
/// Add a socket to watch
///
/// \param socket : Socket to add
///
////////////////////////////////////////////////////////////
void Add(SocketHelper::SocketType socket);
////////////////////////////////////////////////////////////
/// Remove a socket
///
/// \param socket : Socket to remove
///
////////////////////////////////////////////////////////////
void Remove(SocketHelper::SocketType socket);
////////////////////////////////////////////////////////////
/// Remove all sockets
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// Wait and collect sockets which are ready for reading.
/// This functions will return either when at least one socket
/// is ready, or when the given time is out
///
/// \param timeout : Timeout, in seconds (0 by default : no timeout)
///
/// \return Number of sockets ready to be read
///
////////////////////////////////////////////////////////////
unsigned int Wait(float timeout = 0.f);
////////////////////////////////////////////////////////////
/// After a call to Wait(), get the Index-th socket which is
/// ready for reading. The total number of sockets ready
/// is the integer returned by the previous call to Wait()
///
/// \param index : Index of the socket to get
///
/// \return The index-th socket
///
////////////////////////////////////////////////////////////
SocketHelper::SocketType GetSocketReady(unsigned int index) const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
fd_set mySet; ///< Set of socket to watch
fd_set mySetReady; ///< Set of socket which are ready for reading
int myMaxSocket; ///< Maximum socket index
};
} // namespace sf
#endif // SFML_SELECTORBASE_HPP

View file

@ -0,0 +1,234 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKET_HPP
#define SFML_SOCKET_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHandle.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <vector>
namespace sf
{
class SocketSelector;
////////////////////////////////////////////////////////////
/// \brief Base class for all the socket types
///
////////////////////////////////////////////////////////////
class SFML_API Socket : NonCopyable
{
public :
////////////////////////////////////////////////////////////
/// \brief Status codes that may be returned by socket functions
///
////////////////////////////////////////////////////////////
enum Status
{
Done, ///< The socket has sent / received the data
NotReady, ///< The socket is not ready to send / receive data yet
Disconnected, ///< The TCP socket has been disconnected
Error ///< An unexpected error happened
};
////////////////////////////////////////////////////////////
/// \brief Some special values used by sockets
///
////////////////////////////////////////////////////////////
enum
{
AnyPort = 0 ///< Special value that tells the system to pick any available port
};
public :
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
virtual ~Socket();
////////////////////////////////////////////////////////////
/// \brief Set the blocking state of the socket
///
/// In blocking mode, calls will not return until they have
/// completed their task. For example, a call to Receive in
/// blocking mode won't return until some data was actually
/// received.
/// In non-blocking mode, calls will always return immediately,
/// using the return code to signal whether there was data
/// available or not.
/// By default, all sockets are blocking.
///
/// \param blocking True to set the socket as blocking, false for non-blocking
///
/// \see IsBlocking
///
////////////////////////////////////////////////////////////
void SetBlocking(bool blocking);
////////////////////////////////////////////////////////////
/// \brief Tell whether the socket is blocking or non-blocking mode
///
/// \return True if the socket is blocking, false otherwise
///
/// \see SetBlocking
///
////////////////////////////////////////////////////////////
bool IsBlocking() const;
protected :
////////////////////////////////////////////////////////////
/// \brief Types of protocols that the socket can use
///
////////////////////////////////////////////////////////////
enum Type
{
Tcp, ///< TCP protocol
Udp ///< UDP protocol
};
////////////////////////////////////////////////////////////
/// \brief Structure holding the data of a pending packet
///
////////////////////////////////////////////////////////////
struct PendingPacket
{
PendingPacket();
Uint32 Size; ///< Data of packet size
std::size_t SizeReceived; ///< Number of size bytes received so far
std::vector<char> Data; ///< Data of the packet
};
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// This constructor can only be accessed by derived classes.
///
/// \param type Type of the socket (TCP or UDP)
///
////////////////////////////////////////////////////////////
Socket(Type type);
////////////////////////////////////////////////////////////
/// \brief Return the internal handle of the socket
///
/// The returned handle may be invalid if the socket
/// was not created yet (or already destroyed).
/// This function can only be accessed by derived classes.
///
/// \return The internal (OS-specific) handle of the socket
///
////////////////////////////////////////////////////////////
SocketHandle GetHandle() const;
////////////////////////////////////////////////////////////
/// \brief Create the internal representation of the socket
///
/// This function can only be accessed by derived classes.
///
////////////////////////////////////////////////////////////
void Create();
////////////////////////////////////////////////////////////
/// \brief Create the internal representation of the socket
/// from a socket handle
///
/// This function can only be accessed by derived classes.
///
/// \param handle OS-specific handle of the socket to wrap
///
////////////////////////////////////////////////////////////
void Create(SocketHandle handle);
////////////////////////////////////////////////////////////
/// \brief Close the socket gracefully
///
/// This function can only be accessed by derived classes.
///
////////////////////////////////////////////////////////////
void Close();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
PendingPacket myPendingPacket; ///< Temporary data of the packet currently being received
private :
friend class SocketSelector;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
Type myType; ///< Type of the socket (TCP or UDP)
SocketHandle mySocket; ///< Socket descriptor
bool myIsBlocking; ///< Current blocking mode of the socket
};
} // namespace sf
#endif // SFML_SOCKET_HPP
////////////////////////////////////////////////////////////
/// \class sf::Socket
///
/// This class mainly defines internal stuff to be used by
/// derived classes.
///
/// The only public features that it defines, and which
/// is therefore common to all the socket classes, is the
/// blocking state. All sockets can be set as blocking or
/// non-blocking.
///
/// In blocking mode, socket functions will hang until
/// the operation completes, which means that the entire
/// program (well, in fact the current thread if you use
/// multiple ones) will be stuck waiting for your socket
/// operation to complete.
///
/// In non-blocking mode, all the socket functions will
/// return immediately. If the socket is not ready to complete
/// the requested operation, the function simply returns
/// the proper status code (Socket::NotReady).
///
/// The default mode, which is blocking, is the one that is
/// generally used, in combination with threads or selectors.
/// The non-blocking mode is rather used in real-time
/// applications that run an endless loop that can poll
/// the socket often enough, and cannot afford blocking
/// this loop.
///
/// \see sf::TcpListener, sf::TcpSocket, sf::UdpSocket
///
////////////////////////////////////////////////////////////

View file

@ -22,43 +22,36 @@
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPER_HPP
#define SFML_SOCKETHELPER_HPP
#ifndef SFML_SOCKETHANDLE_HPP
#define SFML_SOCKETHANDLE_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
#if defined(SFML_SYSTEM_WINDOWS)
#include <BaseTsd.h>
#endif
namespace sf
{
namespace Socket
{
////////////////////////////////////////////////////////////
/// Enumeration of status returned by socket functions
////////////////////////////////////////////////////////////
enum Status
{
Done, ///< The socket has sent / received the data
NotReady, ///< The socket is not ready to send / receive data yet
Disconnected, ///< The TCP socket has been disconnected
Error ///< An unexpected error happened
};
}
////////////////////////////////////////////////////////////
// Define the low-level socket handle type, specific to
// each platform
////////////////////////////////////////////////////////////
#if defined(SFML_SYSTEM_WINDOWS)
typedef UINT_PTR SocketHandle;
#else
typedef int SocketHandle;
#endif
} // namespace sf
#ifdef SFML_SYSTEM_WINDOWS
#include <SFML/Network/Win32/SocketHelper.hpp>
#else
#include <SFML/Network/Unix/SocketHelper.hpp>
#endif
#endif // SFML_SOCKETHELPER_HPP
#endif // SFML_SOCKETHANDLE_HPP

View file

@ -0,0 +1,251 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETSELECTOR_HPP
#define SFML_SOCKETSELECTOR_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Config.hpp>
namespace sf
{
class Socket;
////////////////////////////////////////////////////////////
/// \brief Multiplexer that allows to read from multiple sockets
///
////////////////////////////////////////////////////////////
class SFML_API SocketSelector
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
SocketSelector();
////////////////////////////////////////////////////////////
/// \brief Copy constructor
///
/// \param copy Instance to copy
///
////////////////////////////////////////////////////////////
SocketSelector(const SocketSelector& copy);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~SocketSelector();
////////////////////////////////////////////////////////////
/// \brief Add a new socket to the selector
///
/// This function keeps a weak reference to the socket,
/// so you have to make sure that the socket is not destroyed
/// while it is stored in the selector.
///
/// \param socket Reference to the socket to add
///
/// \see Remove, Clear
///
////////////////////////////////////////////////////////////
void Add(Socket& socket);
////////////////////////////////////////////////////////////
/// \brief Remove a socket from the selector
///
/// This function doesn't destroy the socket, it simply
/// removes the reference that the selector has to it.
///
/// \param socket Reference to the socket to remove
///
/// \see Add, Clear
///
////////////////////////////////////////////////////////////
void Remove(Socket& socket);
////////////////////////////////////////////////////////////
/// \brief Remove all the sockets stored in the selector
///
/// This function doesn't destroy any instance, it simply
/// removes all the references that the selector has to
/// external sockets.
///
/// \see Add, Remove
///
////////////////////////////////////////////////////////////
void Clear();
////////////////////////////////////////////////////////////
/// \brief Wait until one or more sockets are ready to receive
///
/// This function returns as soon as at least one socket has
/// some data available to be received. To know which sockets are
/// ready, use the IsReady function.
/// If you use a timeout and no socket is ready before the timeout
/// is over, the function returns false.
///
/// \return True if there are sockets ready, false otherwise
///
/// \see IsReady
///
////////////////////////////////////////////////////////////
bool Wait(float timeout = 0.f);
////////////////////////////////////////////////////////////
/// \brief Test a socket to know if it is ready to receive data
///
/// This function must be used after a call to Wait, to know
/// which sockets are ready to receive data. If a socket is
/// ready, a call to Receive will never block because we know
/// that there is data available to read.
/// Note that if this function returns true for a TcpListener,
/// this means that it is ready to accept a new connection.
///
/// \return True if the socket is ready to read, false otherwise
///
/// \see IsReady
///
////////////////////////////////////////////////////////////
bool IsReady(Socket& socket) const;
////////////////////////////////////////////////////////////
/// \brief Overload of assignment operator
///
/// \param right Instance to assign
///
/// \return Reference to self
///
////////////////////////////////////////////////////////////
SocketSelector& operator =(const SocketSelector& right);
private :
struct SocketSelectorImpl;
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketSelectorImpl* myImpl; ///< Opaque pointer to the implementation (which requires OS-specific types)
};
} // namespace sf
#endif // SFML_SOCKETSELECTOR_HPP
////////////////////////////////////////////////////////////
/// \class sf::SocketSelector
///
/// Socket selectors provide a way to wait until some data is
/// available on a set of sockets, instead of just one. This
/// is convenient when you have multiple sockets that may
/// possibly receive data, but you don't know which one will
/// be ready first. In particular, it avoids to use a thread
/// for each socket; with selectors, a single thread can handle
/// all the sockets.
///
/// All types of sockets can be used in a selector:
/// \li sf::TcpListener
/// \li sf::TcpSocket
/// \li sf::UdpSocket
///
/// A selector doesn't store its own copies of the sockets
/// (socket classes are not copyable anyway), it simply keeps
/// a reference to the original sockets that you pass to the
/// Add function. Therefore, you can't use the selector as a
/// socket container, you must store them oustide and make sure
/// that they are alive as long as they are used in the selector.
///
/// Using a selector is simple:
/// \li populate the selector with all the sockets that you want to observe
/// \li make it wait until there is data available on any of the sockets
/// \li test each socket to find out which ones are ready
///
/// Usage example:
/// \code
/// // Create a socket to listen to new connections
/// sf::TcpListener listener;
/// listener.Listen(55001);
///
/// // Create a list to store the future clients
/// std::list<sf::TcpSocket*> clients;
///
/// // Create a selector
/// sf::SocketSelector selector;
///
/// // Add the listener to the selector
/// selector.Add(listener);
///
/// // Endless loop that waits for new connections
/// while (running)
/// {
/// // Make the selector wait for data on any socket
/// if (selector.Wait())
/// {
/// // Test the listener
/// if (selector.IsReady(listener))
/// {
/// // The listener is ready: there is a pending connection
/// sf::TcpSocket* client = new sf::TcpSocket;
/// if (listener.accept(*client) == sf::Socket::Done)
/// {
/// // Add the new client to the clients list
/// clients.push_back(client);
///
/// // Add the new client to the selector so that we will
/// // be notified when he sends something
/// selector.Add(*client);
/// }
/// }
/// else
/// {
/// // The listener socket is not ready, test all other sockets (the clients)
/// for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
/// {
/// sf::TcpSocket& client = **it;
/// if (selector.IsReady(client))
/// {
/// // The client has sent some data, we can receive it
/// sf::Packet packet;
/// if (client.Receive(packet) == sf::Socket::Done)
/// {
/// ...
/// }
/// }
/// }
/// }
/// }
/// }
/// \endcode
///
/// \see sf::Socket
///
////////////////////////////////////////////////////////////

View file

@ -1,227 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETTCP_HPP
#define SFML_SOCKETTCP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
#include <vector>
namespace sf
{
class Packet;
class IpAddress;
template <typename> class Selector;
////////////////////////////////////////////////////////////
/// SocketTCP wraps a socket using TCP protocol to
/// send data safely (but a bit slower)
////////////////////////////////////////////////////////////
class SFML_API SocketTCP
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SocketTCP();
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket.
/// The default behaviour of a socket is blocking
///
/// \param blocking : Pass true to set the socket as blocking, or false for non-blocking
///
////////////////////////////////////////////////////////////
void SetBlocking(bool blocking);
////////////////////////////////////////////////////////////
/// Connect to another computer on a specified port
///
/// \param port : Port to use for transfers (warning : ports < 1024 are reserved)
/// \param host : IP Address of the host to connect to
/// \param timeout : Maximum time to wait, in seconds (0 by default : no timeout) (this parameter is ignored for non-blocking sockets)
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
Socket::Status Connect(unsigned short port, const IpAddress& host, float timeout = 0.f);
////////////////////////////////////////////////////////////
/// Listen to a specified port for incoming data or connections
///
/// \param port : Port to listen to
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Listen(unsigned short port);
////////////////////////////////////////////////////////////
/// Wait for a connection (must be listening to a port).
/// This function will block if the socket is blocking
///
/// \param connected : Socket containing the connection with the connected client
/// \param address : Pointer to an address to fill with client infos
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Accept(SocketTCP& connected, IpAddress* address = NULL);
////////////////////////////////////////////////////////////
/// Send an array of bytes to the host (must be connected first)
///
/// \param data : Pointer to the bytes to send
/// \param sizeInBytes : Number of bytes to send
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(const char* data, std::size_t sizeInBytes);
////////////////////////////////////////////////////////////
/// Receive an array of bytes from the host (must be connected first).
/// This function will block if the socket is blocking
///
/// \param data : Pointer to a byte array to fill (make sure it is big enough)
/// \param maxSize : Maximum number of bytes to read
/// \param sizeReceived : Number of bytes received
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(char* data, std::size_t maxSize, std::size_t& sizeReceived);
////////////////////////////////////////////////////////////
/// Send a packet of data to the host (must be connected first)
///
/// \param packet : Packet to send
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(Packet& packet);
////////////////////////////////////////////////////////////
/// Receive a packet from the host (must be connected first).
/// This function will block if the socket is blocking
///
/// \param packet : Packet to fill with received data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(Packet& packet);
////////////////////////////////////////////////////////////
/// Close the socket
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Close();
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
///
/// \return True if the socket is valid
///
////////////////////////////////////////////////////////////
bool IsValid() const;
////////////////////////////////////////////////////////////
/// Comparison operator ==
///
/// \param other : Socket to compare
///
/// \return True if *this == other
///
////////////////////////////////////////////////////////////
bool operator ==(const SocketTCP& other) const;
////////////////////////////////////////////////////////////
/// Comparison operator !=
///
/// \param other : Socket to compare
///
/// \return True if *this != other
///
////////////////////////////////////////////////////////////
bool operator !=(const SocketTCP& other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
///
/// \param other : Socket to compare
///
/// \return True if *this < other
///
////////////////////////////////////////////////////////////
bool operator <(const SocketTCP& other) const;
private :
friend class Selector<SocketTCP>;
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
///
/// \param descriptor : Socket descriptor
///
////////////////////////////////////////////////////////////
SocketTCP(SocketHelper::SocketType descriptor);
////////////////////////////////////////////////////////////
/// Create the socket
///
/// \param descriptor : System socket descriptor to use (0 by default -- create a new socket)
///
////////////////////////////////////////////////////////////
void Create(SocketHelper::SocketType descriptor = 0);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketHelper::SocketType mySocket; ///< Socket descriptor
Uint32 myPendingHeader; ///< Data of the current pending packet header, if any
Uint32 myPendingHeaderSize; ///< Size of the current pending packet header, if any
std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any
Int32 myPendingPacketSize; ///< Size of the current pending packet, if any
bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
};
} // namespace sf
#endif // SFML_SOCKETTCP_HPP

View file

@ -1,228 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETUDP_HPP
#define SFML_SOCKETUDP_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/SocketHelper.hpp>
#include <vector>
namespace sf
{
class Packet;
class IpAddress;
template <typename> class Selector;
////////////////////////////////////////////////////////////
/// SocketUDP wraps a socket using UDP protocol to
/// send data fastly (but with less safety)
////////////////////////////////////////////////////////////
class SFML_API SocketUDP
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
SocketUDP();
////////////////////////////////////////////////////////////
/// Change the blocking state of the socket.
/// The default behaviour of a socket is blocking
///
/// \param blocking : Pass true to set the socket as blocking, or false for non-blocking
///
////////////////////////////////////////////////////////////
void SetBlocking(bool blocking);
////////////////////////////////////////////////////////////
/// Bind the socket to a specific port
///
/// \param port : Port to bind the socket to
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Bind(unsigned short port);
////////////////////////////////////////////////////////////
/// Unbind the socket from its previous port, if any
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Unbind();
////////////////////////////////////////////////////////////
/// Send an array of bytes
///
/// \param data : Pointer to the bytes to send
/// \param sizeInBytes : Number of bytes to send
/// \param address : Address of the computer to send the packet to
/// \param port : Port to send the data to
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(const char* data, std::size_t sizeInBytes, const IpAddress& address, unsigned short port);
////////////////////////////////////////////////////////////
/// Receive an array of bytes.
/// This function will block if the socket is blocking
///
/// \param data : Pointer to a byte array to fill (make sure it is big enough)
/// \param maxSize : Maximum number of bytes to read
/// \param sizeReceived : Number of bytes received
/// \param address : Address of the computer which sent the data
/// \param port : Port on which the remote computer sent the data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(char* data, std::size_t maxSize, std::size_t& sizeReceived, IpAddress& address, unsigned short& port);
////////////////////////////////////////////////////////////
/// Send a packet of data
///
/// \param packet : Packet to send
/// \param address : Address of the computer to send the packet to
/// \param port : Port to send the data to
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Send(Packet& packet, const IpAddress& address, unsigned short port);
////////////////////////////////////////////////////////////
/// Receive a packet.
/// This function will block if the socket is blocking
///
/// \param packet : Packet to fill with received data
/// \param Address : Address of the computer which sent the packet
/// \param Port : Port on which the remote computer sent the data
///
/// \return Status code
///
////////////////////////////////////////////////////////////
Socket::Status Receive(Packet& packet, IpAddress& address, unsigned short& port);
////////////////////////////////////////////////////////////
/// Close the socket
///
/// \return True if operation has been successful
///
////////////////////////////////////////////////////////////
bool Close();
////////////////////////////////////////////////////////////
/// Check if the socket is in a valid state ; this function
/// can be called any time to check if the socket is OK
///
/// \return True if the socket is valid
///
////////////////////////////////////////////////////////////
bool IsValid() const;
////////////////////////////////////////////////////////////
/// Get the port the socket is currently bound to
///
/// \return Current port (0 means the socket is not bound)
///
////////////////////////////////////////////////////////////
unsigned short GetPort() const;
////////////////////////////////////////////////////////////
/// Comparison operator ==
///
/// \param other : Socket to compare
///
/// \return True if *this == other
///
////////////////////////////////////////////////////////////
bool operator ==(const SocketUDP& other) const;
////////////////////////////////////////////////////////////
/// Comparison operator !=
///
/// \param other : Socket to compare
///
/// \return True if *this != other
///
////////////////////////////////////////////////////////////
bool operator !=(const SocketUDP& other) const;
////////////////////////////////////////////////////////////
/// Comparison operator <.
/// Provided for compatibility with standard containers, as
/// comparing two sockets doesn't make much sense...
///
/// \param other : Socket to compare
///
/// \return True if *this < other
///
////////////////////////////////////////////////////////////
bool operator <(const SocketUDP& other) const;
private :
friend class Selector<SocketUDP>;
////////////////////////////////////////////////////////////
/// Construct the socket from a socket descriptor
/// (for internal use only)
///
/// \param descriptor : Socket descriptor
///
////////////////////////////////////////////////////////////
SocketUDP(SocketHelper::SocketType descriptor);
////////////////////////////////////////////////////////////
/// Create the socket
///
/// \param descriptor : System socket descriptor to use (0 by default -- create a new socket)
///
////////////////////////////////////////////////////////////
void Create(SocketHelper::SocketType descriptor = 0);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
SocketHelper::SocketType mySocket; ///< Socket identifier
unsigned short myPort; ///< Port to which the socket is bound
Uint32 myPendingHeader; ///< Data of the current pending packet header, if any
Uint32 myPendingHeaderSize; ///< Size of the current pending packet header, if any
std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any
Int32 myPendingPacketSize; ///< Size of the current pending packet, if any
bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
};
} // namespace sf
#endif // SFML_SOCKETUDP_HPP

View file

@ -0,0 +1,131 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_TCPLISTENER_HPP
#define SFML_TCPLISTENER_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Socket.hpp>
namespace sf
{
class TcpSocket;
////////////////////////////////////////////////////////////
/// \brief Socket that listens to new TCP connections
///
////////////////////////////////////////////////////////////
class SFML_API TcpListener : public Socket
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
TcpListener();
////////////////////////////////////////////////////////////
/// \brief Start listening for connections
///
/// This functions makes the socket listen to the specified
/// port, waiting for new connections.
/// If the socket was previously listening to another port,
/// it will be stopped first and bound to the new port.
///
/// \param port Port to listen for new connections
///
/// \return Status code
///
/// \see Accept, Close
///
////////////////////////////////////////////////////////////
Status Listen(unsigned short port);
////////////////////////////////////////////////////////////
/// \brief Accept a new connection
///
/// If the socket is in blocking mode, this function will
/// not return until a connection is actually received.
///
/// \param socket Socket that will hold the new connection
///
/// \return Status code
///
/// \see Listen
///
////////////////////////////////////////////////////////////
Status Accept(TcpSocket& socket);
};
} // namespace sf
#endif // SFML_TCPLISTENER_HPP
////////////////////////////////////////////////////////////
/// \class sf::TcpListener
///
/// A listener socket is a special type of socket that listens to
/// a given port and waits for connections on that port.
/// This is all it can do.
///
/// When a new connection is received, the socket returns a
/// new instance of sf::TcpSocket that is properly
/// initialized and can be used to communicate with the
/// new client.
///
/// Listener sockets are specific to the TCP protocol,
/// UDP sockets are connectionless and can therefore communicate
/// directly. As a consequence, a listener socket will always
/// return the new connections as sf::TcpSocket instances.
///
/// Usage example:
/// \code
/// // Create a listener socket and make it wait for new
/// // connections on port 55001
/// sf::TcpListener listener;
/// listener.Listen(55001);
///
/// // Endless loop that waits for new connections
/// while (running)
/// {
/// sf::TcpSocket client;
/// if (listener.accept(client) == sf::Socket::Done)
/// {
/// // A new client just connected!
/// std::cout << "New connection received from " << client.GetRemoteAddress() << std::endl;
/// DoSomethingWith(client);
/// }
/// }
/// \endcode
///
/// \see sf::TcpSocket, sf::Socket
///
////////////////////////////////////////////////////////////

View file

@ -0,0 +1,271 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_TCPSOCKET_HPP
#define SFML_TCPSOCKET_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Socket.hpp>
namespace sf
{
class TcpListener;
class IpAddress;
class Packet;
////////////////////////////////////////////////////////////
/// \brief Specialized socket using the TCP protocol
///
////////////////////////////////////////////////////////////
class SFML_API TcpSocket : public Socket
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
TcpSocket();
////////////////////////////////////////////////////////////
/// \brief Get the port to which the socket is bound locally
///
/// If the socket is not connected, this function returns 0.
///
/// \return Port to which the socket is bound
///
/// \see Connect, GetRemotePort
///
////////////////////////////////////////////////////////////
unsigned short GetLocalPort() const;
////////////////////////////////////////////////////////////
/// \brief Get the address of the connected peer
///
/// It the socket is not connected, this function returns
/// sf::IpAddress::None.
///
/// \return Address of the remote peer
///
/// \see GetRemotePort
///
////////////////////////////////////////////////////////////
IpAddress GetRemoteAddress() const;
////////////////////////////////////////////////////////////
/// \brief Get the port of the connected peer to which
/// the socket is connected
///
/// If the socket is not connected, this function returns 0.
///
/// \return Remote port to which the socket is connected
///
/// \see GetRemoteAddress
///
////////////////////////////////////////////////////////////
unsigned short GetRemotePort() const;
////////////////////////////////////////////////////////////
/// \brief Connect the socket to a remote peer
///
/// In blocking mode, this function may take a while, especially
/// if the remote peer is not reachable. The last parameter allows
/// you to stop trying to connect after a given timeout.
/// If the socket was previously connected, it is first disconnected.
///
/// \param remoteAddress Address of the remote peer
/// \param remotePort Port of the remote peer
/// \param timeout Optional maximum time to wait, in seconds
///
/// \return Status code
///
/// \see Disconnect
///
////////////////////////////////////////////////////////////
Status Connect(const IpAddress& remoteAddress, unsigned short remotePort, float timeout = 0.f);
////////////////////////////////////////////////////////////
/// \brief Disconnect the connect from its remote peer
///
/// This function gracefully closes the connection. If the
/// socket is not connected, this function has no effect.
///
/// \see Connect
///
////////////////////////////////////////////////////////////
void Disconnect();
////////////////////////////////////////////////////////////
/// \brief Send raw data to the remote peer
///
/// This function will fail if the socket is not connected.
///
/// \param data Pointer to the sequence of bytes to send
/// \param size Number of bytes to send
///
/// \return Status code
///
/// \see Receive
///
////////////////////////////////////////////////////////////
Status Send(const char* data, std::size_t size);
////////////////////////////////////////////////////////////
/// \brief Receive raw data from the remote peer
///
/// In blocking mode, this function will wait until some
/// bytes are actually received.
/// This function will fail if the socket is not connected.
///
/// \param data Pointer to the array to fill with the received bytes
/// \param size Maximum number of bytes that can be received
/// \param received This variable is filled with the actual number of bytes received
///
/// \return Status code
///
/// \see Send
///
////////////////////////////////////////////////////////////
Status Receive(char* data, std::size_t size, std::size_t& received);
////////////////////////////////////////////////////////////
/// \brief Send a formatted packet of data to the remote peer
///
/// This function will fail if the socket is not connected.
///
/// \param packet Packet to send
///
/// \return Status code
///
/// \see Receive
///
////////////////////////////////////////////////////////////
Status Send(Packet& packet);
////////////////////////////////////////////////////////////
/// \brief Receive a formatted packet of data from the remote peer
///
/// In blocking mode, this function will wait until the whole packet
/// has been received.
/// This function will fail if the socket is not connected.
///
/// \param packet Packet to fill with the received data
///
/// \return Status code
///
/// \see Send
///
////////////////////////////////////////////////////////////
Status Receive(Packet& packet);
friend class TcpListener;
};
} // namespace sf
#endif // SFML_TCPSOCKET_HPP
////////////////////////////////////////////////////////////
/// \class sf::TcpSocket
///
/// TCP is a connected protocol, which means that a TCP
/// socket can only communicate with the host it is connected
/// to. It can't send or receive anything if it is not connected.
///
/// The TCP protocol is reliable but adds a slight overhead.
/// It ensures that your data will always be received in order
/// and without errors (no data corrupted, lost or duplicated).
///
/// When a socket is connected to a remote host, you can
/// retrieve informations about this host with the
/// GetRemoteAddress and GetRemotePort functions. You can
/// also get the local port to which the socket is bound
/// (which is automatically chosen when the socket is connected),
/// with the GetLocalPort function.
///
/// Sending and receiving data can use either the low-level
/// or the high-level functions. The low-level functions
/// process a raw sequence of bytes, and cannot ensure that
/// one call to Send will exactly match one call to Receive
/// at the other end of the socket.
///
/// The high-level interface uses packets (see sf::Packet),
/// which are easier to use and provide more safety regarding
/// the data that is exchanged. You can look at the sf::Packet
/// class to get more details about how they work.
///
/// The socket is automatically disconnected when it is destroyed,
/// but if you want to explicitely close the connection while
/// the socket instance is still alive, you can call Disconnect.
///
/// Usage example:
/// \code
/// // ----- The client -----
///
/// // Create a socket and connect it to 192.168.1.50 on port 55001
/// sf::TcpSocket socket;
/// socket.Connect("192.168.1.50", 55001);
///
/// // Send a message to the connected host
/// std::string message = "Hi, I am a client";
/// socket.Send(message.c_str(), message.size() + 1);
///
/// // Receive an answer from the server
/// char buffer[1024];
/// std::size_t received = 0;
/// socket.Receive(buffer, sizeof(buffer), received);
/// std::cout << "The server said: " << buffer << std::endl;
/// }
///
/// // ----- The server -----
///
/// // Create a listener to wait for incoming connections on port 55001
/// sf::TcpListener listener;
/// listener.Listen(55001);
///
/// // Wait for a connection
/// sf::TcpSocket socket;
/// listener.Accept(socket);
/// std::cout << "New client connected: " << socket.GetRemoteAddress() << std::endl;
///
/// // Receive a message from the client
/// char buffer[1024];
/// std::size_t received = 0;
/// socket.Receive(buffer, sizeof(buffer), received);
/// std::cout << "The client said: " << buffer << std::endl;
///
/// // Send an answer
/// std::string message = "Welcome, client";
/// socket.Send(message.c_str(), message.size() + 1);
/// }
/// \endcode
///
/// \see sf::Socket, sf::UdpSocket, sf::Packet
///
////////////////////////////////////////////////////////////

View file

@ -0,0 +1,242 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_UDPSOCKET_HPP
#define SFML_UDPSOCKET_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network/Socket.hpp>
namespace sf
{
class IpAddress;
class Packet;
////////////////////////////////////////////////////////////
/// \brief Specialized socket using the UDP protocol
///
////////////////////////////////////////////////////////////
class SFML_API UdpSocket : public Socket
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
UdpSocket();
////////////////////////////////////////////////////////////
/// \brief Get the port to which the socket is bound locally
///
/// If the socket is not bound to a port, this function
/// returns 0.
///
/// \return Port to which the socket is bound
///
/// \see Bind
///
////////////////////////////////////////////////////////////
unsigned short GetLocalPort() const;
////////////////////////////////////////////////////////////
/// \brief Bind the socket to a specific port
///
/// Binding the socket to a port is necessary for being
/// able to receive data on that port.
/// You can use the special value Socket::AnyPort to tell the
/// system to automatically pick an available port, and then
/// call GetLocalPort to retrieve the chosen port.
///
/// \param port Port to bind the socket to
///
/// \return Status code
///
/// \see Unbind, GetLocalPort
///
////////////////////////////////////////////////////////////
Status Bind(unsigned short port);
////////////////////////////////////////////////////////////
/// \brief Unbind the socket from the local port to which it is bound
///
/// The port that the socket was previously using is immediately
/// available after this function is called. If the
/// socket is not bound to a port, this function has no effect.
///
/// \see Bind
///
////////////////////////////////////////////////////////////
void Unbind();
////////////////////////////////////////////////////////////
/// \brief Send raw data to a remote peer
///
/// \param data Pointer to the sequence of bytes to send
/// \param size Number of bytes to send
/// \param remoteAddress Address of the receiver
/// \param remotePort Port of the receiver to send the data to
///
/// \return Status code
///
/// \see Receive
///
////////////////////////////////////////////////////////////
Status Send(const char* data, std::size_t size, const IpAddress& remoteAddress, unsigned short remotePort);
////////////////////////////////////////////////////////////
/// \brief Receive raw data from a remote peer
///
/// In blocking mode, this function will wait until some
/// bytes are actually received.
///
/// \param data Pointer to the array to fill with the received bytes
/// \param size Maximum number of bytes that can be received
/// \param received This variable is filled with the actual number of bytes received
/// \param remoteAddress Address of the peer that sent the data
/// \param remotePort Port of the peer that sent the data
///
/// \return Status code
///
/// \see Send
///
////////////////////////////////////////////////////////////
Status Receive(char* data, std::size_t size, std::size_t& received, IpAddress& remoteAddress, unsigned short& remotePort);
////////////////////////////////////////////////////////////
/// \brief Send a formatted packet of data to a remote peer
///
/// \param packet Packet to send
/// \param remoteAddress Address of the receiver
/// \param remotePort Port of the receiver to send the data to
///
/// \return Status code
///
/// \see Receive
///
////////////////////////////////////////////////////////////
Status Send(Packet& packet, const IpAddress& remoteAddress, unsigned short remotePort);
////////////////////////////////////////////////////////////
/// \brief Receive a formatted packet of data from a remote peer
///
/// In blocking mode, this function will wait until the whole packet
/// has been received.
///
/// \param packet Packet to fill with the received data
/// \param remoteAddress Address of the peer that sent the data
/// \param remotePort Port of the peer that sent the data
///
/// \return Status code
///
/// \see Send
///
////////////////////////////////////////////////////////////
Status Receive(Packet& packet, IpAddress& remoteAddress, unsigned short& remotePort);
};
} // namespace sf
#endif // SFML_UDPSOCKET_HPP
////////////////////////////////////////////////////////////
/// \class sf::UdpSocket
///
/// A UDP socket is a connectionless socket. Instead of
/// connecting once to a remote host, like TCP sockets,
/// it can send to and receive from any host at any time.
///
/// The UDP protocol is lightweight but unreliable. Unreliable
/// means that the data may be corrupted, duplicated, lost or
/// arrive out of order. UDP is generally used for real-time
/// communication (audio or video streaming, real-time games,
/// etc.) where speed is crucial and corrupted data
/// doesn't matter much.
///
/// Sending and receiving data can use either the low-level
/// or the high-level functions. The low-level functions
/// process a raw sequence of bytes, and cannot ensure that
/// one call to Send will exactly match one call to Receive
/// at the other end of the socket.
///
/// The high-level interface uses packets (see sf::Packet),
/// which are easier to use and provide more safety regarding
/// the data that is exchanged. You can look at the sf::Packet
/// class to get more details about how they work.
///
/// If the socket is bound to a port, it is automatically
/// unbound from it when the socket is destroyed. However,
/// you can unbind the socket explicitely with the Unbind
/// function if necessary, to stop receiving messages or
/// make the port available for other sockets.
///
/// Usage example:
/// \code
/// // ----- The client -----
///
/// // Create a socket and bind it to the port 55001
/// sf::UdpSocket socket;
/// socket.Bind(55001);
///
/// // Send a message to 192.168.1.50 on port 55002
/// std::string message = "Hi, I am " + sf::IpAddress::GetLocalAddress().ToString();
/// socket.Send(message.c_str(), message.size() + 1, "192.168.1.50", 55002);
///
/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
/// char buffer[1024];
/// std::size_t received = 0;
/// sf::IpAddress sender;
/// unsigned short port;
/// socket.Receive(buffer, sizeof(buffer), received, sender, port);
/// std::cout << sender.ToString() << " said: " << buffer << std::endl;
/// }
///
/// // ----- The server -----
///
/// // Create a socket and bind it to the port 55002
/// sf::UdpSocket socket;
/// socket.Bind(55002);
///
/// // Receive a message from anyone
/// char buffer[1024];
/// std::size_t received = 0;
/// sf::IpAddress sender;
/// unsigned short port;
/// socket.Receive(buffer, sizeof(buffer), received, sender, port);
/// std::cout << sender.ToString() << " said: " << buffer << std::endl;
///
/// // Send an answer
/// std::string message = "Welcome " + sender.ToString();
/// socket.Send(message.c_str(), message.size() + 1, sender, port);
/// }
/// \endcode
///
/// \see sf::Socket, sf::TcpSocket, sf::Packet
///
////////////////////////////////////////////////////////////

View file

@ -1,96 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPERUNIX_HPP
#define SFML_SOCKETHELPERUNIX_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// This class defines helper functions to do all the
/// non-portable socket stuff. This class is meant for internal
/// use only
////////////////////////////////////////////////////////////
class SFML_API SocketHelper
{
public :
////////////////////////////////////////////////////////////
// Define some socket types
////////////////////////////////////////////////////////////
typedef int SocketType;
typedef socklen_t LengthType;
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
///
/// \return Unique value of the invalid socket
///
////////////////////////////////////////////////////////////
static SocketType InvalidSocket();
////////////////////////////////////////////////////////////
/// Close / destroy a socket
///
/// \param Socket : Socket to close
///
/// \return True on success
///
////////////////////////////////////////////////////////////
static bool Close(SocketType Socket);
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
///
/// \param Socket : Socket to modify
/// \param Block : New blocking state of the socket
///
////////////////////////////////////////////////////////////
static void SetBlocking(SocketType Socket, bool Block);
////////////////////////////////////////////////////////////
/// Get the last socket error status
///
/// \return Status corresponding to the last socket error
///
////////////////////////////////////////////////////////////
static Socket::Status GetErrorStatus();
};
} // namespace sf
#endif // SFML_SOCKETHELPERUNIX_HPP

View file

@ -1,90 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_SOCKETHELPERWIN32_HPP
#define SFML_SOCKETHELPERWIN32_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <winsock2.h>
namespace sf
{
////////////////////////////////////////////////////////////
/// This class defines helper functions to do all the
/// non-portable socket stuff. This class is meant for internal
/// use only
////////////////////////////////////////////////////////////
class SFML_API SocketHelper
{
public :
////////////////////////////////////////////////////////////
// Define some socket types
////////////////////////////////////////////////////////////
typedef SOCKET SocketType;
typedef int LengthType;
////////////////////////////////////////////////////////////
/// Return the value of the invalid socket
///
/// \return Unique value of the invalid socket
///
////////////////////////////////////////////////////////////
static SocketType InvalidSocket();
////////////////////////////////////////////////////////////
/// Close / destroy a socket
///
/// \param socket : Socket to close
///
/// \return True on success
///
////////////////////////////////////////////////////////////
static bool Close(SocketType socket);
////////////////////////////////////////////////////////////
/// Set a socket as blocking or non-blocking
///
/// \param socket : Socket to modify
/// \param block : New blocking state of the socket
///
////////////////////////////////////////////////////////////
static void SetBlocking(SocketType socket, bool block);
////////////////////////////////////////////////////////////
/// Get the last socket error status
///
/// \return Status corresponding to the last socket error
///
////////////////////////////////////////////////////////////
static Socket::Status GetErrorStatus();
};
} // namespace sf
#endif // SFML_SOCKETHELPERWIN32_HPP