diff options
author | James Cowgill <james410@cowgill.org.uk> | 2014-12-09 20:21:40 +0000 |
---|---|---|
committer | James Cowgill <james410@cowgill.org.uk> | 2014-12-09 20:21:40 +0000 |
commit | fa21c65d0c764705cfc377bf0d0de08fac26874e (patch) | |
tree | dbc9e87bbd8684d15e79fc0c8b7a8985389c3b35 /include/SFML/Network | |
parent | dd835931261c340acd5f0409341d13fa2670423e (diff) |
Imported Upstream version 2.2.0+dfsg
Diffstat (limited to 'include/SFML/Network')
-rw-r--r-- | include/SFML/Network/Export.hpp | 2 | ||||
-rw-r--r-- | include/SFML/Network/Ftp.hpp | 1199 | ||||
-rw-r--r-- | include/SFML/Network/Http.hpp | 949 | ||||
-rw-r--r-- | include/SFML/Network/IpAddress.hpp | 632 | ||||
-rw-r--r-- | include/SFML/Network/Packet.hpp | 818 | ||||
-rw-r--r-- | include/SFML/Network/Socket.hpp | 436 | ||||
-rw-r--r-- | include/SFML/Network/SocketHandle.hpp | 114 | ||||
-rw-r--r-- | include/SFML/Network/SocketSelector.hpp | 526 | ||||
-rw-r--r-- | include/SFML/Network/TcpListener.hpp | 324 | ||||
-rw-r--r-- | include/SFML/Network/TcpSocket.hpp | 584 | ||||
-rw-r--r-- | include/SFML/Network/UdpSocket.hpp | 566 |
11 files changed, 3093 insertions, 3057 deletions
diff --git a/include/SFML/Network/Export.hpp b/include/SFML/Network/Export.hpp index 7dcd1d0..030b8d5 100644 --- a/include/SFML/Network/Export.hpp +++ b/include/SFML/Network/Export.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) +// Copyright (C) 2007-2014 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. diff --git a/include/SFML/Network/Ftp.hpp b/include/SFML/Network/Ftp.hpp index 9b8ed9b..4dd242b 100644 --- a/include/SFML/Network/Ftp.hpp +++ b/include/SFML/Network/Ftp.hpp @@ -1,591 +1,608 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_FTP_HPP
-#define SFML_FTP_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Network/Export.hpp>
-#include <SFML/Network/TcpSocket.hpp>
-#include <SFML/System/NonCopyable.hpp>
-#include <SFML/System/Time.hpp>
-#include <string>
-#include <vector>
-
-
-namespace sf
-{
-class IpAddress;
-
-////////////////////////////////////////////////////////////
-/// \brief A FTP client
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API Ftp : NonCopyable
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Enumeration of transfer modes
- ///
- ////////////////////////////////////////////////////////////
- enum TransferMode
- {
- Binary, ///< Binary mode (file is transfered as a sequence of bytes)
- Ascii, ///< Text mode using ASCII encoding
- Ebcdic ///< Text mode using EBCDIC encoding
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Define a FTP response
- ///
- ////////////////////////////////////////////////////////////
- class SFML_NETWORK_API Response
- {
- public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Status codes possibly returned by a FTP response
- ///
- ////////////////////////////////////////////////////////////
- enum Status
- {
- // 1xx: the requested action is being initiated,
- // expect another reply before proceeding with a new command
- RestartMarkerReply = 110, ///< Restart marker reply
- ServiceReadySoon = 120, ///< Service ready in N minutes
- DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting
- OpeningDataConnection = 150, ///< File status ok, about to open data connection
-
- // 2xx: the requested action has been successfully completed
- Ok = 200, ///< Command ok
- PointlessCommand = 202, ///< Command not implemented
- SystemStatus = 211, ///< System status, or system help reply
- DirectoryStatus = 212, ///< Directory status
- FileStatus = 213, ///< File status
- HelpMessage = 214, ///< Help message
- SystemType = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document
- ServiceReady = 220, ///< Service ready for new user
- ClosingConnection = 221, ///< Service closing control connection
- DataConnectionOpened = 225, ///< Data connection open, no transfer in progress
- ClosingDataConnection = 226, ///< Closing data connection, requested file action successful
- EnteringPassiveMode = 227, ///< Entering passive mode
- LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate
- FileActionOk = 250, ///< Requested file action ok
- DirectoryOk = 257, ///< PATHNAME created
-
- // 3xx: the command has been accepted, but the requested action
- // is dormant, pending receipt of further information
- NeedPassword = 331, ///< User name ok, need password
- NeedAccountToLogIn = 332, ///< Need account for login
- NeedInformation = 350, ///< Requested file action pending further information
-
- // 4xx: the command was not accepted and the requested action did not take place,
- // but the error condition is temporary and the action may be requested again
- ServiceUnavailable = 421, ///< Service not available, closing control connection
- DataConnectionUnavailable = 425, ///< Can't open data connection
- TransferAborted = 426, ///< Connection closed, transfer aborted
- FileActionAborted = 450, ///< Requested file action not taken
- LocalError = 451, ///< Requested action aborted, local error in processing
- InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable
-
- // 5xx: the command was not accepted and
- // the requested action did not take place
- CommandUnknown = 500, ///< Syntax error, command unrecognized
- ParametersUnknown = 501, ///< Syntax error in parameters or arguments
- CommandNotImplemented = 502, ///< Command not implemented
- BadCommandSequence = 503, ///< Bad sequence of commands
- ParameterNotImplemented = 504, ///< Command not implemented for that parameter
- NotLoggedIn = 530, ///< Not logged in
- NeedAccountToStore = 532, ///< Need account for storing files
- FileUnavailable = 550, ///< Requested action not taken, file unavailable
- PageTypeUnknown = 551, ///< Requested action aborted, page type unknown
- NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation
- FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed
-
- // 10xx: SFML custom codes
- InvalidResponse = 1000, ///< Response is not a valid FTP one
- ConnectionFailed = 1001, ///< Connection with server failed
- ConnectionClosed = 1002, ///< Connection with server closed
- InvalidFile = 1003 ///< Invalid file to upload / download
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// This constructor is used by the FTP client to build
- /// the response.
- ///
- /// \param code Response status code
- /// \param message Response message
- ///
- ////////////////////////////////////////////////////////////
- explicit Response(Status code = InvalidResponse, const std::string& message = "");
-
- ////////////////////////////////////////////////////////////
- /// \brief Check if the status code means a success
- ///
- /// 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;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the status code of the response
- ///
- /// \return Status code
- ///
- ////////////////////////////////////////////////////////////
- Status getStatus() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the full message contained in the response
- ///
- /// \return The response message
- ///
- ////////////////////////////////////////////////////////////
- const std::string& getMessage() const;
-
- private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- Status m_status; ///< Status code returned from the server
- std::string m_message; ///< Last message received from the server
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Specialization of FTP response returning a directory
- ///
- ////////////////////////////////////////////////////////////
- class SFML_NETWORK_API DirectoryResponse : public Response
- {
- public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// \param response Source response
- ///
- ////////////////////////////////////////////////////////////
- DirectoryResponse(const Response& response);
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the directory returned in the response
- ///
- /// \return Directory name
- ///
- ////////////////////////////////////////////////////////////
- const std::string& getDirectory() const;
-
- private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- std::string m_directory; ///< Directory extracted from the response message
- };
-
-
- ////////////////////////////////////////////////////////////
- /// \brief Specialization of FTP response returning a
- /// filename lisiting
- ////////////////////////////////////////////////////////////
- class SFML_NETWORK_API ListingResponse : public Response
- {
- public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// \param response Source response
- /// \param data Data containing the raw listing
- ///
- ////////////////////////////////////////////////////////////
- ListingResponse(const Response& response, const std::vector<char>& data);
-
- ////////////////////////////////////////////////////////////
- /// \brief Return the array of directory/file names
- ///
- /// \return Array containing the requested listing
- ///
- ////////////////////////////////////////////////////////////
- const std::vector<std::string>& getListing() const;
-
- private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- std::vector<std::string> m_listing; ///< Directory/file names extracted from the data
- };
-
-
- ////////////////////////////////////////////////////////////
- /// \brief Destructor
- ///
- /// Automatically closes the connection with the server if
- /// it is still opened.
- ///
- ////////////////////////////////////////////////////////////
- ~Ftp();
-
- ////////////////////////////////////////////////////////////
- /// \brief Connect to the specified FTP server
- ///
- /// 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, Time::Zero, 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
- ///
- /// \return Server response to the request
- ///
- /// \see disconnect
- ///
- ////////////////////////////////////////////////////////////
- Response connect(const IpAddress& server, unsigned short port = 21, Time timeout = Time::Zero);
-
- ////////////////////////////////////////////////////////////
- /// \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
- ///
- ////////////////////////////////////////////////////////////
- Response login();
-
- ////////////////////////////////////////////////////////////
- /// \brief Log in using a username and a 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
- ///
- ////////////////////////////////////////////////////////////
- Response login(const std::string& name, const std::string& password);
-
- ////////////////////////////////////////////////////////////
- /// \brief Send a null command to keep the connection alive
- ///
- /// This command is useful because the server may close the
- /// connection automatically if no command is sent.
- ///
- /// \return Server response to the request
- ///
- ////////////////////////////////////////////////////////////
- Response keepAlive();
-
- ////////////////////////////////////////////////////////////
- /// \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();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the contents of the given directory
- ///
- /// 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 = "");
-
- ////////////////////////////////////////////////////////////
- /// \brief Change the current working directory
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Go to the parent directory of the current one
- ///
- /// \return Server response to the request
- ///
- /// \see getWorkingDirectory, getDirectoryListing, changeDirectory
- ///
- ////////////////////////////////////////////////////////////
- Response parentDirectory();
-
- ////////////////////////////////////////////////////////////
- /// \brief Create a new directory
- ///
- /// 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 createDirectory(const std::string& name);
-
- ////////////////////////////////////////////////////////////
- /// \brief Remove an existing directory
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Rename an existing file
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Remove an existing file
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Download a file from the server
- ///
- /// 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.
- ///
- /// \param remoteFile Filename of the distant file to download
- /// \param localPath Where to put to file on the local computer
- /// \param mode Transfer mode
- ///
- /// \return Server response to the request
- ///
- /// \see upload
- ///
- ////////////////////////////////////////////////////////////
- Response download(const std::string& remoteFile, const std::string& localPath, TransferMode mode = Binary);
-
- ////////////////////////////////////////////////////////////
- /// \brief Upload a file to the server
- ///
- /// 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.
- ///
- /// \param localFile Path of the local file to upload
- /// \param remotePath Where to put to file on the server
- /// \param mode Transfer mode
- ///
- /// \return Server response to the request
- ///
- /// \see download
- ///
- ////////////////////////////////////////////////////////////
- Response upload(const std::string& localFile, const std::string& remotePath, TransferMode mode = Binary);
-
-private :
-
- ////////////////////////////////////////////////////////////
- /// \brief Send a command to the FTP server
- ///
- /// \param command Command to send
- /// \param parameter Command parameter
- ///
- /// \return Server response to the request
- ///
- ////////////////////////////////////////////////////////////
- Response sendCommand(const std::string& command, const std::string& parameter = "");
-
- ////////////////////////////////////////////////////////////
- /// \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
- ///
- ////////////////////////////////////////////////////////////
- Response getResponse();
-
- ////////////////////////////////////////////////////////////
- /// \brief Utility class for exchanging datas with the server
- /// on the data channel
- ///
- ////////////////////////////////////////////////////////////
- class DataChannel;
-
- friend class DataChannel;
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- TcpSocket m_commandSocket; ///< Socket holding the control connection with the server
-};
-
-} // namespace sf
-
-
-#endif // SFML_FTP_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::Ftp
-/// \ingroup network
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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_FTP_HPP +#define SFML_FTP_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Export.hpp> +#include <SFML/Network/TcpSocket.hpp> +#include <SFML/System/NonCopyable.hpp> +#include <SFML/System/Time.hpp> +#include <string> +#include <vector> + + +namespace sf +{ +class IpAddress; + +//////////////////////////////////////////////////////////// +/// \brief A FTP client +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API Ftp : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Enumeration of transfer modes + /// + //////////////////////////////////////////////////////////// + enum TransferMode + { + Binary, ///< Binary mode (file is transfered as a sequence of bytes) + Ascii, ///< Text mode using ASCII encoding + Ebcdic ///< Text mode using EBCDIC encoding + }; + + //////////////////////////////////////////////////////////// + /// \brief Define a FTP response + /// + //////////////////////////////////////////////////////////// + class SFML_NETWORK_API Response + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Status codes possibly returned by a FTP response + /// + //////////////////////////////////////////////////////////// + enum Status + { + // 1xx: the requested action is being initiated, + // expect another reply before proceeding with a new command + RestartMarkerReply = 110, ///< Restart marker reply + ServiceReadySoon = 120, ///< Service ready in N minutes + DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting + OpeningDataConnection = 150, ///< File status ok, about to open data connection + + // 2xx: the requested action has been successfully completed + Ok = 200, ///< Command ok + PointlessCommand = 202, ///< Command not implemented + SystemStatus = 211, ///< System status, or system help reply + DirectoryStatus = 212, ///< Directory status + FileStatus = 213, ///< File status + HelpMessage = 214, ///< Help message + SystemType = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document + ServiceReady = 220, ///< Service ready for new user + ClosingConnection = 221, ///< Service closing control connection + DataConnectionOpened = 225, ///< Data connection open, no transfer in progress + ClosingDataConnection = 226, ///< Closing data connection, requested file action successful + EnteringPassiveMode = 227, ///< Entering passive mode + LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate + FileActionOk = 250, ///< Requested file action ok + DirectoryOk = 257, ///< PATHNAME created + + // 3xx: the command has been accepted, but the requested action + // is dormant, pending receipt of further information + NeedPassword = 331, ///< User name ok, need password + NeedAccountToLogIn = 332, ///< Need account for login + NeedInformation = 350, ///< Requested file action pending further information + + // 4xx: the command was not accepted and the requested action did not take place, + // but the error condition is temporary and the action may be requested again + ServiceUnavailable = 421, ///< Service not available, closing control connection + DataConnectionUnavailable = 425, ///< Can't open data connection + TransferAborted = 426, ///< Connection closed, transfer aborted + FileActionAborted = 450, ///< Requested file action not taken + LocalError = 451, ///< Requested action aborted, local error in processing + InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable + + // 5xx: the command was not accepted and + // the requested action did not take place + CommandUnknown = 500, ///< Syntax error, command unrecognized + ParametersUnknown = 501, ///< Syntax error in parameters or arguments + CommandNotImplemented = 502, ///< Command not implemented + BadCommandSequence = 503, ///< Bad sequence of commands + ParameterNotImplemented = 504, ///< Command not implemented for that parameter + NotLoggedIn = 530, ///< Not logged in + NeedAccountToStore = 532, ///< Need account for storing files + FileUnavailable = 550, ///< Requested action not taken, file unavailable + PageTypeUnknown = 551, ///< Requested action aborted, page type unknown + NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation + FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed + + // 10xx: SFML custom codes + InvalidResponse = 1000, ///< Response is not a valid FTP one + ConnectionFailed = 1001, ///< Connection with server failed + ConnectionClosed = 1002, ///< Connection with server closed + InvalidFile = 1003 ///< Invalid file to upload / download + }; + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor is used by the FTP client to build + /// the response. + /// + /// \param code Response status code + /// \param message Response message + /// + //////////////////////////////////////////////////////////// + explicit Response(Status code = InvalidResponse, const std::string& message = ""); + + //////////////////////////////////////////////////////////// + /// \brief Check if the status code means a success + /// + /// 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; + + //////////////////////////////////////////////////////////// + /// \brief Get the status code of the response + /// + /// \return Status code + /// + //////////////////////////////////////////////////////////// + Status getStatus() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the full message contained in the response + /// + /// \return The response message + /// + //////////////////////////////////////////////////////////// + const std::string& getMessage() const; + + private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Status m_status; ///< Status code returned from the server + std::string m_message; ///< Last message received from the server + }; + + //////////////////////////////////////////////////////////// + /// \brief Specialization of FTP response returning a directory + /// + //////////////////////////////////////////////////////////// + class SFML_NETWORK_API DirectoryResponse : public Response + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// \param response Source response + /// + //////////////////////////////////////////////////////////// + DirectoryResponse(const Response& response); + + //////////////////////////////////////////////////////////// + /// \brief Get the directory returned in the response + /// + /// \return Directory name + /// + //////////////////////////////////////////////////////////// + const std::string& getDirectory() const; + + private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::string m_directory; ///< Directory extracted from the response message + }; + + + //////////////////////////////////////////////////////////// + /// \brief Specialization of FTP response returning a + /// filename listing + //////////////////////////////////////////////////////////// + class SFML_NETWORK_API ListingResponse : public Response + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// \param response Source response + /// \param data Data containing the raw listing + /// + //////////////////////////////////////////////////////////// + ListingResponse(const Response& response, const std::string& data); + + //////////////////////////////////////////////////////////// + /// \brief Return the array of directory/file names + /// + /// \return Array containing the requested listing + /// + //////////////////////////////////////////////////////////// + const std::vector<std::string>& getListing() const; + + private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::vector<std::string> m_listing; ///< Directory/file names extracted from the data + }; + + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// Automatically closes the connection with the server if + /// it is still opened. + /// + //////////////////////////////////////////////////////////// + ~Ftp(); + + //////////////////////////////////////////////////////////// + /// \brief Connect to the specified FTP server + /// + /// 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, Time::Zero, 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 + /// + /// \return Server response to the request + /// + /// \see disconnect + /// + //////////////////////////////////////////////////////////// + Response connect(const IpAddress& server, unsigned short port = 21, Time timeout = Time::Zero); + + //////////////////////////////////////////////////////////// + /// \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 + /// + //////////////////////////////////////////////////////////// + Response login(); + + //////////////////////////////////////////////////////////// + /// \brief Log in using a username and a 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 + /// + //////////////////////////////////////////////////////////// + Response login(const std::string& name, const std::string& password); + + //////////////////////////////////////////////////////////// + /// \brief Send a null command to keep the connection alive + /// + /// This command is useful because the server may close the + /// connection automatically if no command is sent. + /// + /// \return Server response to the request + /// + //////////////////////////////////////////////////////////// + Response keepAlive(); + + //////////////////////////////////////////////////////////// + /// \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(); + + //////////////////////////////////////////////////////////// + /// \brief Get the contents of the given directory + /// + /// 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 = ""); + + //////////////////////////////////////////////////////////// + /// \brief Change the current working directory + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Go to the parent directory of the current one + /// + /// \return Server response to the request + /// + /// \see getWorkingDirectory, getDirectoryListing, changeDirectory + /// + //////////////////////////////////////////////////////////// + Response parentDirectory(); + + //////////////////////////////////////////////////////////// + /// \brief Create a new directory + /// + /// 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 createDirectory(const std::string& name); + + //////////////////////////////////////////////////////////// + /// \brief Remove an existing directory + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Rename an existing file + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Remove an existing file + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Download a file from the server + /// + /// 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 a file with the same filename as the distant file + /// already exists in the local destination path, it will + /// be overwritten. + /// + /// \param remoteFile Filename of the distant file to download + /// \param localPath The directory in which to put the file on the local computer + /// \param mode Transfer mode + /// + /// \return Server response to the request + /// + /// \see upload + /// + //////////////////////////////////////////////////////////// + Response download(const std::string& remoteFile, const std::string& localPath, TransferMode mode = Binary); + + //////////////////////////////////////////////////////////// + /// \brief Upload a file to the server + /// + /// 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. + /// + /// \param localFile Path of the local file to upload + /// \param remotePath The directory in which to put the file on the server + /// \param mode Transfer mode + /// + /// \return Server response to the request + /// + /// \see download + /// + //////////////////////////////////////////////////////////// + Response upload(const std::string& localFile, const std::string& remotePath, TransferMode mode = Binary); + + //////////////////////////////////////////////////////////// + /// \brief Send a command to the FTP server + /// + /// While the most often used commands are provided as member + /// functions in the sf::Ftp class, this method can be used + /// to send any FTP command to the server. If the command + /// requires one or more parameters, they can be specified + /// in \a parameter. If the server returns information, you + /// can extract it from the response using Response::getMessage(). + /// + /// \param command Command to send + /// \param parameter Command parameter + /// + /// \return Server response to the request + /// + //////////////////////////////////////////////////////////// + Response sendCommand(const std::string& command, const std::string& parameter = ""); + +private: + + //////////////////////////////////////////////////////////// + /// \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 + /// + //////////////////////////////////////////////////////////// + Response getResponse(); + + //////////////////////////////////////////////////////////// + /// \brief Utility class for exchanging datas with the server + /// on the data channel + /// + //////////////////////////////////////////////////////////// + class DataChannel; + + friend class DataChannel; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + TcpSocket m_commandSocket; ///< Socket holding the control connection with the server +}; + +} // namespace sf + + +#endif // SFML_FTP_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Ftp +/// \ingroup network +/// +/// 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 implicitly 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. The most often used +/// commands are directly provided as member functions, but it is +/// also possible to use specific commands with the sendCommand() method. +/// +/// 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; +/// +/// // Send specific commands (here: FEAT to list supported FTP features) +/// response = ftp.sendCommand("FEAT"); +/// if (response.isOk()) +/// std::cout << "Feature list:\n" << response.getMessage() << std::endl; +/// +/// // Disconnect from the server (optional) +/// ftp.disconnect(); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/Http.hpp b/include/SFML/Network/Http.hpp index 7338f5a..fec109c 100644 --- a/include/SFML/Network/Http.hpp +++ b/include/SFML/Network/Http.hpp @@ -1,467 +1,482 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_HTTP_HPP
-#define SFML_HTTP_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Network/Export.hpp>
-#include <SFML/Network/IpAddress.hpp>
-#include <SFML/Network/TcpSocket.hpp>
-#include <SFML/System/NonCopyable.hpp>
-#include <SFML/System/Time.hpp>
-#include <map>
-#include <string>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// \brief A HTTP client
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API Http : NonCopyable
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Define a HTTP request
- ///
- ////////////////////////////////////////////////////////////
- class SFML_NETWORK_API Request
- {
- public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Enumerate the available HTTP methods for a request
- ///
- ////////////////////////////////////////////////////////////
- enum Method
- {
- Get, ///< Request in get mode, standard method to retrieve a page
- Post, ///< Request in post mode, usually to send data to a page
- Head ///< Request a page's header only
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// 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(const std::string& uri = "/", Method method = Get, const std::string& body = "");
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the value of a 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the request method
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the requested URI
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the HTTP version for the request
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the body of the request
- ///
- /// 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);
-
- private :
-
- friend class Http;
-
- ////////////////////////////////////////////////////////////
- /// \brief Prepare the final request to send to the server
- ///
- /// 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 prepare() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Check if the request defines a field
- ///
- /// This function uses case-insensitive comparisons.
- ///
- /// \param field Name of the field to test
- ///
- /// \return True if the field exists, false otherwise
- ///
- ////////////////////////////////////////////////////////////
- bool hasField(const std::string& field) const;
-
- ////////////////////////////////////////////////////////////
- // Types
- ////////////////////////////////////////////////////////////
- typedef std::map<std::string, std::string> FieldTable;
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- FieldTable m_fields; ///< Fields of the header associated to their value
- Method m_method; ///< Method to use for the request
- std::string m_uri; ///< Target URI of the request
- unsigned int m_majorVersion; ///< Major HTTP version
- unsigned int m_minorVersion; ///< Minor HTTP version
- std::string m_body; ///< Body of the request
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Define a HTTP response
- ///
- ////////////////////////////////////////////////////////////
- class SFML_NETWORK_API Response
- {
- public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Enumerate all the valid status codes for a response
- ///
- ////////////////////////////////////////////////////////////
- enum Status
- {
- // 2xx: success
- Ok = 200, ///< Most common code returned when operation was successful
- Created = 201, ///< The resource has successfully been created
- Accepted = 202, ///< The request has been accepted, but will be processed later by the server
- NoContent = 204, ///< The server didn't send any data in return
- ResetContent = 205, ///< The server informs the client that it should clear the view (form) that caused the request to be sent
- PartialContent = 206, ///< The server has sent a part of the resource, as a response to a partial GET request
-
- // 3xx: redirection
- MultipleChoices = 300, ///< The requested page can be accessed from several locations
- MovedPermanently = 301, ///< The requested page has permanently moved to a new location
- MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
- NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
-
- // 4xx: client error
- BadRequest = 400, ///< The server couldn't understand the request (syntax error)
- Unauthorized = 401, ///< The requested page needs an authentification to be accessed
- Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
- NotFound = 404, ///< The requested page doesn't exist
- RangeNotSatisfiable = 407, ///< The server can't satisfy the partial GET request (with a "Range" header field)
-
- // 5xx: server error
- InternalServerError = 500, ///< The server encountered an unexpected error
- NotImplemented = 501, ///< The server doesn't implement a requested feature
- BadGateway = 502, ///< The gateway server has received an error from the source server
- ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
- GatewayTimeout = 504, ///< The gateway server couldn't receive a response from the source server
- VersionNotSupported = 505, ///< The server doesn't support the requested HTTP version
-
- // 10xx: SFML custom codes
- InvalidResponse = 1000, ///< Response is not a valid HTTP one
- ConnectionFailed = 1001 ///< Connection with server failed
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// Constructs an empty response.
- ///
- ////////////////////////////////////////////////////////////
- Response();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the value of a field
- ///
- /// 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
- ///
- ////////////////////////////////////////////////////////////
- const std::string& getField(const std::string& field) const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the response 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;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the major HTTP version number of the response
- ///
- /// \return Major HTTP version number
- ///
- /// \see getMinorHttpVersion
- ///
- ////////////////////////////////////////////////////////////
- unsigned int getMajorHttpVersion() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the minor HTTP version number of the response
- ///
- /// \return Minor HTTP version number
- ///
- /// \see getMajorHttpVersion
- ///
- ////////////////////////////////////////////////////////////
- unsigned int getMinorHttpVersion() const;
-
- ////////////////////////////////////////////////////////////
- /// \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
- ///
- ////////////////////////////////////////////////////////////
- const std::string& getBody() const;
-
- private :
-
- friend class Http;
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the header from a response string
- ///
- /// This function is used by Http to build the response
- /// of a request.
- ///
- /// \param data Content of the response to parse
- ///
- ////////////////////////////////////////////////////////////
- void parse(const std::string& data);
-
- ////////////////////////////////////////////////////////////
- // Types
- ////////////////////////////////////////////////////////////
- typedef std::map<std::string, std::string> FieldTable;
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- FieldTable m_fields; ///< Fields of the header
- Status m_status; ///< Status code
- unsigned int m_majorVersion; ///< Major HTTP version
- unsigned int m_minorVersion; ///< Minor HTTP version
- std::string m_body; ///< Body of the response
- };
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- ////////////////////////////////////////////////////////////
- Http();
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the HTTP client with the target host
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Set the target host
- ///
- /// 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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Send a HTTP request and return the server's response.
- ///
- /// 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 Time::Zero 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
- ///
- /// \return Server's response
- ///
- ////////////////////////////////////////////////////////////
- Response sendRequest(const Request& request, Time timeout = Time::Zero);
-
-private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- TcpSocket m_connection; ///< Connection to the host
- IpAddress m_host; ///< Web host address
- std::string m_hostName; ///< Web host name
- unsigned short m_port; ///< Port used for connection with host
-};
-
-} // namespace sf
-
-
-#endif // SFML_HTTP_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::Http
-/// \ingroup network
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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_HTTP_HPP +#define SFML_HTTP_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Export.hpp> +#include <SFML/Network/IpAddress.hpp> +#include <SFML/Network/TcpSocket.hpp> +#include <SFML/System/NonCopyable.hpp> +#include <SFML/System/Time.hpp> +#include <map> +#include <string> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief A HTTP client +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API Http : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Define a HTTP request + /// + //////////////////////////////////////////////////////////// + class SFML_NETWORK_API Request + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Enumerate the available HTTP methods for a request + /// + //////////////////////////////////////////////////////////// + enum Method + { + Get, ///< Request in get mode, standard method to retrieve a page + Post, ///< Request in post mode, usually to send data to a page + Head, ///< Request a page's header only + Put, ///< Request in put mode, useful for a REST API + Delete ///< Request in delete mode, useful for a REST API + }; + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// 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(const std::string& uri = "/", Method method = Get, const std::string& body = ""); + + //////////////////////////////////////////////////////////// + /// \brief Set the value of a 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); + + //////////////////////////////////////////////////////////// + /// \brief Set the request method + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Set the requested URI + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Set the HTTP version for the request + /// + /// 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); + + //////////////////////////////////////////////////////////// + /// \brief Set the body of the request + /// + /// 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); + + private: + + friend class Http; + + //////////////////////////////////////////////////////////// + /// \brief Prepare the final request to send to the server + /// + /// 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 prepare() const; + + //////////////////////////////////////////////////////////// + /// \brief Check if the request defines a field + /// + /// This function uses case-insensitive comparisons. + /// + /// \param field Name of the field to test + /// + /// \return True if the field exists, false otherwise + /// + //////////////////////////////////////////////////////////// + bool hasField(const std::string& field) const; + + //////////////////////////////////////////////////////////// + // Types + //////////////////////////////////////////////////////////// + typedef std::map<std::string, std::string> FieldTable; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + FieldTable m_fields; ///< Fields of the header associated to their value + Method m_method; ///< Method to use for the request + std::string m_uri; ///< Target URI of the request + unsigned int m_majorVersion; ///< Major HTTP version + unsigned int m_minorVersion; ///< Minor HTTP version + std::string m_body; ///< Body of the request + }; + + //////////////////////////////////////////////////////////// + /// \brief Define a HTTP response + /// + //////////////////////////////////////////////////////////// + class SFML_NETWORK_API Response + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Enumerate all the valid status codes for a response + /// + //////////////////////////////////////////////////////////// + enum Status + { + // 2xx: success + Ok = 200, ///< Most common code returned when operation was successful + Created = 201, ///< The resource has successfully been created + Accepted = 202, ///< The request has been accepted, but will be processed later by the server + NoContent = 204, ///< The server didn't send any data in return + ResetContent = 205, ///< The server informs the client that it should clear the view (form) that caused the request to be sent + PartialContent = 206, ///< The server has sent a part of the resource, as a response to a partial GET request + + // 3xx: redirection + MultipleChoices = 300, ///< The requested page can be accessed from several locations + MovedPermanently = 301, ///< The requested page has permanently moved to a new location + MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location + NotModified = 304, ///< For conditional requests, means the requested page hasn't changed and doesn't need to be refreshed + + // 4xx: client error + BadRequest = 400, ///< The server couldn't understand the request (syntax error) + Unauthorized = 401, ///< The requested page needs an authentication to be accessed + Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentication + NotFound = 404, ///< The requested page doesn't exist + RangeNotSatisfiable = 407, ///< The server can't satisfy the partial GET request (with a "Range" header field) + + // 5xx: server error + InternalServerError = 500, ///< The server encountered an unexpected error + NotImplemented = 501, ///< The server doesn't implement a requested feature + BadGateway = 502, ///< The gateway server has received an error from the source server + ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...) + GatewayTimeout = 504, ///< The gateway server couldn't receive a response from the source server + VersionNotSupported = 505, ///< The server doesn't support the requested HTTP version + + // 10xx: SFML custom codes + InvalidResponse = 1000, ///< Response is not a valid HTTP one + ConnectionFailed = 1001 ///< Connection with server failed + }; + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Constructs an empty response. + /// + //////////////////////////////////////////////////////////// + Response(); + + //////////////////////////////////////////////////////////// + /// \brief Get the value of a field + /// + /// 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 + /// + //////////////////////////////////////////////////////////// + const std::string& getField(const std::string& field) const; + + //////////////////////////////////////////////////////////// + /// \brief Get the response 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; + + //////////////////////////////////////////////////////////// + /// \brief Get the major HTTP version number of the response + /// + /// \return Major HTTP version number + /// + /// \see getMinorHttpVersion + /// + //////////////////////////////////////////////////////////// + unsigned int getMajorHttpVersion() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the minor HTTP version number of the response + /// + /// \return Minor HTTP version number + /// + /// \see getMajorHttpVersion + /// + //////////////////////////////////////////////////////////// + unsigned int getMinorHttpVersion() const; + + //////////////////////////////////////////////////////////// + /// \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 + /// + //////////////////////////////////////////////////////////// + const std::string& getBody() const; + + private: + + friend class Http; + + //////////////////////////////////////////////////////////// + /// \brief Construct the header from a response string + /// + /// This function is used by Http to build the response + /// of a request. + /// + /// \param data Content of the response to parse + /// + //////////////////////////////////////////////////////////// + void parse(const std::string& data); + + + //////////////////////////////////////////////////////////// + /// \brief Read values passed in the answer header + /// + /// This function is used by Http to extract values passed + /// in the response. + /// + /// \param in String stream containing the header values + /// + //////////////////////////////////////////////////////////// + void parseFields(std::istream &in); + + //////////////////////////////////////////////////////////// + // Types + //////////////////////////////////////////////////////////// + typedef std::map<std::string, std::string> FieldTable; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + FieldTable m_fields; ///< Fields of the header + Status m_status; ///< Status code + unsigned int m_majorVersion; ///< Major HTTP version + unsigned int m_minorVersion; ///< Minor HTTP version + std::string m_body; ///< Body of the response + }; + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + Http(); + + //////////////////////////////////////////////////////////// + /// \brief Construct the HTTP client with the target host + /// + /// 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). 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); + + //////////////////////////////////////////////////////////// + /// \brief Set the target host + /// + /// 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). 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); + + //////////////////////////////////////////////////////////// + /// \brief Send a HTTP request and return the server's response. + /// + /// 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 Time::Zero means that the client will use the system default timeout + /// (which is usually pretty long). + /// + /// \param request Request to send + /// \param timeout Maximum time to wait + /// + /// \return Server's response + /// + //////////////////////////////////////////////////////////// + Response sendRequest(const Request& request, Time timeout = Time::Zero); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + TcpSocket m_connection; ///< Connection to the host + IpAddress m_host; ///< Web host address + std::string m_hostName; ///< Web host name + unsigned short m_port; ///< Port used for connection with host +}; + +} // namespace sf + + +#endif // SFML_HTTP_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Http +/// \ingroup network +/// +/// 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 HTTPS protocol is +/// not supported. +/// +/// 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 +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/IpAddress.hpp b/include/SFML/Network/IpAddress.hpp index 15c4ac3..77b0cf5 100644 --- a/include/SFML/Network/IpAddress.hpp +++ b/include/SFML/Network/IpAddress.hpp @@ -1,316 +1,316 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_IPADDRESS_HPP
-#define SFML_IPADDRESS_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Network/Export.hpp>
-#include <SFML/System/Time.hpp>
-#include <istream>
-#include <ostream>
-#include <string>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// \brief Encapsulate an IPv4 network address
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API IpAddress
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// This constructor creates an empty (invalid) address
- ///
- ////////////////////////////////////////////////////////////
- IpAddress();
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the address from a string
- ///
- /// Here \a address can be either a decimal address
- /// (ex: "192.168.1.56") or a network name (ex: "localhost").
- ///
- /// \param address IP address or network name
- ///
- ////////////////////////////////////////////////////////////
- IpAddress(const std::string& address);
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the address from a string
- ///
- /// Here \a address can be either a decimal address
- /// (ex: "192.168.1.56") or a network name (ex: "localhost").
- /// This is equivalent to the constructor taking a std::string
- /// parameter, it is defined for convenience so that the
- /// implicit conversions from literal strings to IpAddress work.
- ///
- /// \param address IP address or network name
- ///
- ////////////////////////////////////////////////////////////
- IpAddress(const char* address);
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the address from 4 bytes
- ///
- /// Calling IpAddress(a, b, c, d) is equivalent to calling
- /// IpAddress("a.b.c.d"), but safer as it doesn't have to
- /// parse a string to get the address components.
- ///
- /// \param byte0 First byte of the address
- /// \param byte1 Second byte of the address
- /// \param byte2 Third byte of the address
- /// \param byte3 Fourth byte of the address
- ///
- ////////////////////////////////////////////////////////////
- IpAddress(Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3);
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the address from a 32-bits integer
- ///
- /// This constructor uses the internal representation of
- /// the address directly. It should be used for optimization
- /// purposes, and only if you got that representation from
- /// IpAddress::ToInteger().
- ///
- /// \param address 4 bytes of the address packed into a 32-bits integer
- ///
- /// \see toInteger
- ///
- ////////////////////////////////////////////////////////////
- explicit IpAddress(Uint32 address);
-
- ////////////////////////////////////////////////////////////
- /// \brief Get a string representation of the address
- ///
- /// The returned string is the decimal representation of the
- /// IP address (like "192.168.1.56"), even if it was constructed
- /// from a host name.
- ///
- /// \return String representation of the address
- ///
- /// \see toInteger
- ///
- ////////////////////////////////////////////////////////////
- std::string toString() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get an integer representation of the address
- ///
- /// The returned number is the internal representation of the
- /// address, and should be used for optimization purposes only
- /// (like sending the address through a socket).
- /// The integer produced by this function can then be converted
- /// back to a sf::IpAddress with the proper constructor.
- ///
- /// \return 32-bits unsigned integer representation of the address
- ///
- /// \see toString
- ///
- ////////////////////////////////////////////////////////////
- Uint32 toInteger() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the computer's local address
- ///
- /// The local address is the address of the computer from the
- /// LAN point of view, i.e. something like 192.168.1.56. It is
- /// meaningful only for communications over the local network.
- /// Unlike getPublicAddress, this function is fast and may be
- /// used safely anywhere.
- ///
- /// \return Local IP address of the computer
- ///
- /// \see getPublicAddress
- ///
- ////////////////////////////////////////////////////////////
- static IpAddress getLocalAddress();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the computer's public address
- ///
- /// The public address is the address of the computer from the
- /// internet point of view, i.e. something like 89.54.1.169.
- /// It is necessary for communications over the world wide web.
- /// The only way to get a public address is to ask it to a
- /// distant website; as a consequence, this function depends on
- /// both your network connection and the server, and may be
- /// very slow. You should use it as few as possible. Because
- /// this function depends on the network connection and on a distant
- /// server, you may use a time limit if you don't want your program
- /// to be possibly stuck waiting in case there is a problem; this
- /// limit is deactivated by default.
- ///
- /// \param timeout Maximum time to wait
- ///
- /// \return Public IP address of the computer
- ///
- /// \see getLocalAddress
- ///
- ////////////////////////////////////////////////////////////
- static IpAddress getPublicAddress(Time timeout = Time::Zero);
-
- ////////////////////////////////////////////////////////////
- // Static member data
- ////////////////////////////////////////////////////////////
- static const IpAddress None; ///< Value representing an empty/invalid address
- static const IpAddress LocalHost; ///< The "localhost" address (for connecting a computer to itself locally)
- static const IpAddress Broadcast; ///< The "broadcast" address (for sending UDP messages to everyone on a local network)
-
-private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- Uint32 m_address; ///< Address stored as an unsigned 32 bits integer
-};
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of == operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if both addresses are equal
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator ==(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of != operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if both addresses are different
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator !=(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of < operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if \a left is lesser than \a right
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator <(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of > operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if \a left is greater than \a right
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator >(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of <= operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if \a left is lesser or equal than \a right
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator <=(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of >= operator to compare two IP addresses
-///
-/// \param left Left operand (a IP address)
-/// \param right Right operand (a IP address)
-///
-/// \return True if \a left is greater or equal than \a right
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API bool operator >=(const IpAddress& left, const IpAddress& right);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of >> operator to extract an IP address from an input stream
-///
-/// \param stream Input stream
-/// \param address IP address to extract
-///
-/// \return Reference to the input stream
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API std::istream& operator >>(std::istream& stream, IpAddress& address);
-
-////////////////////////////////////////////////////////////
-/// \brief Overload of << operator to print an IP address to an output stream
-///
-/// \param stream Output stream
-/// \param address IP address to print
-///
-/// \return Reference to the output stream
-///
-////////////////////////////////////////////////////////////
-SFML_NETWORK_API std::ostream& operator <<(std::ostream& stream, const IpAddress& address);
-
-} // namespace sf
-
-
-#endif // SFML_IPADDRESS_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::IpAddress
-/// \ingroup network
-///
-/// sf::IpAddress is a utility class for manipulating network
-/// addresses. It provides a set a implicit constructors and
-/// conversion functions to easily build or transform an IP
-/// address from/to various representations.
-///
-/// Usage example:
-/// \code
-/// sf::IpAddress a0; // an invalid address
-/// sf::IpAddress a1 = sf::IpAddress::None; // an invalid address (same as a0)
-/// sf::IpAddress a2("127.0.0.1"); // the local host address
-/// sf::IpAddress a3 = sf::IpAddress::Broadcast; // the broadcast address
-/// sf::IpAddress a4(192, 168, 1, 56); // a local address
-/// sf::IpAddress a5("my_computer"); // a local address created from a network name
-/// sf::IpAddress a6("89.54.1.169"); // a distant address
-/// sf::IpAddress a7("www.google.com"); // a distant address created from a network name
-/// sf::IpAddress a8 = sf::IpAddress::getLocalAddress(); // my address on the local network
-/// sf::IpAddress a9 = sf::IpAddress::getPublicAddress(); // my address on the internet
-/// \endcode
-///
-/// Note that sf::IpAddress currently doesn't support IPv6
-/// nor other types of network addresses.
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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_IPADDRESS_HPP +#define SFML_IPADDRESS_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Export.hpp> +#include <SFML/System/Time.hpp> +#include <istream> +#include <ostream> +#include <string> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Encapsulate an IPv4 network address +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API IpAddress +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// This constructor creates an empty (invalid) address + /// + //////////////////////////////////////////////////////////// + IpAddress(); + + //////////////////////////////////////////////////////////// + /// \brief Construct the address from a string + /// + /// Here \a address can be either a decimal address + /// (ex: "192.168.1.56") or a network name (ex: "localhost"). + /// + /// \param address IP address or network name + /// + //////////////////////////////////////////////////////////// + IpAddress(const std::string& address); + + //////////////////////////////////////////////////////////// + /// \brief Construct the address from a string + /// + /// Here \a address can be either a decimal address + /// (ex: "192.168.1.56") or a network name (ex: "localhost"). + /// This is equivalent to the constructor taking a std::string + /// parameter, it is defined for convenience so that the + /// implicit conversions from literal strings to IpAddress work. + /// + /// \param address IP address or network name + /// + //////////////////////////////////////////////////////////// + IpAddress(const char* address); + + //////////////////////////////////////////////////////////// + /// \brief Construct the address from 4 bytes + /// + /// Calling IpAddress(a, b, c, d) is equivalent to calling + /// IpAddress("a.b.c.d"), but safer as it doesn't have to + /// parse a string to get the address components. + /// + /// \param byte0 First byte of the address + /// \param byte1 Second byte of the address + /// \param byte2 Third byte of the address + /// \param byte3 Fourth byte of the address + /// + //////////////////////////////////////////////////////////// + IpAddress(Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3); + + //////////////////////////////////////////////////////////// + /// \brief Construct the address from a 32-bits integer + /// + /// This constructor uses the internal representation of + /// the address directly. It should be used for optimization + /// purposes, and only if you got that representation from + /// IpAddress::ToInteger(). + /// + /// \param address 4 bytes of the address packed into a 32-bits integer + /// + /// \see toInteger + /// + //////////////////////////////////////////////////////////// + explicit IpAddress(Uint32 address); + + //////////////////////////////////////////////////////////// + /// \brief Get a string representation of the address + /// + /// The returned string is the decimal representation of the + /// IP address (like "192.168.1.56"), even if it was constructed + /// from a host name. + /// + /// \return String representation of the address + /// + /// \see toInteger + /// + //////////////////////////////////////////////////////////// + std::string toString() const; + + //////////////////////////////////////////////////////////// + /// \brief Get an integer representation of the address + /// + /// The returned number is the internal representation of the + /// address, and should be used for optimization purposes only + /// (like sending the address through a socket). + /// The integer produced by this function can then be converted + /// back to a sf::IpAddress with the proper constructor. + /// + /// \return 32-bits unsigned integer representation of the address + /// + /// \see toString + /// + //////////////////////////////////////////////////////////// + Uint32 toInteger() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the computer's local address + /// + /// The local address is the address of the computer from the + /// LAN point of view, i.e. something like 192.168.1.56. It is + /// meaningful only for communications over the local network. + /// Unlike getPublicAddress, this function is fast and may be + /// used safely anywhere. + /// + /// \return Local IP address of the computer + /// + /// \see getPublicAddress + /// + //////////////////////////////////////////////////////////// + static IpAddress getLocalAddress(); + + //////////////////////////////////////////////////////////// + /// \brief Get the computer's public address + /// + /// The public address is the address of the computer from the + /// internet point of view, i.e. something like 89.54.1.169. + /// It is necessary for communications over the world wide web. + /// The only way to get a public address is to ask it to a + /// distant website; as a consequence, this function depends on + /// both your network connection and the server, and may be + /// very slow. You should use it as few as possible. Because + /// this function depends on the network connection and on a distant + /// server, you may use a time limit if you don't want your program + /// to be possibly stuck waiting in case there is a problem; this + /// limit is deactivated by default. + /// + /// \param timeout Maximum time to wait + /// + /// \return Public IP address of the computer + /// + /// \see getLocalAddress + /// + //////////////////////////////////////////////////////////// + static IpAddress getPublicAddress(Time timeout = Time::Zero); + + //////////////////////////////////////////////////////////// + // Static member data + //////////////////////////////////////////////////////////// + static const IpAddress None; ///< Value representing an empty/invalid address + static const IpAddress LocalHost; ///< The "localhost" address (for connecting a computer to itself locally) + static const IpAddress Broadcast; ///< The "broadcast" address (for sending UDP messages to everyone on a local network) + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Uint32 m_address; ///< Address stored as an unsigned 32 bits integer +}; + +//////////////////////////////////////////////////////////// +/// \brief Overload of == operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if both addresses are equal +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator ==(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of != operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if both addresses are different +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator !=(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of < operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if \a left is lesser than \a right +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator <(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of > operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if \a left is greater than \a right +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator >(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of <= operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if \a left is lesser or equal than \a right +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator <=(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of >= operator to compare two IP addresses +/// +/// \param left Left operand (a IP address) +/// \param right Right operand (a IP address) +/// +/// \return True if \a left is greater or equal than \a right +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API bool operator >=(const IpAddress& left, const IpAddress& right); + +//////////////////////////////////////////////////////////// +/// \brief Overload of >> operator to extract an IP address from an input stream +/// +/// \param stream Input stream +/// \param address IP address to extract +/// +/// \return Reference to the input stream +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API std::istream& operator >>(std::istream& stream, IpAddress& address); + +//////////////////////////////////////////////////////////// +/// \brief Overload of << operator to print an IP address to an output stream +/// +/// \param stream Output stream +/// \param address IP address to print +/// +/// \return Reference to the output stream +/// +//////////////////////////////////////////////////////////// +SFML_NETWORK_API std::ostream& operator <<(std::ostream& stream, const IpAddress& address); + +} // namespace sf + + +#endif // SFML_IPADDRESS_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::IpAddress +/// \ingroup network +/// +/// sf::IpAddress is a utility class for manipulating network +/// addresses. It provides a set a implicit constructors and +/// conversion functions to easily build or transform an IP +/// address from/to various representations. +/// +/// Usage example: +/// \code +/// sf::IpAddress a0; // an invalid address +/// sf::IpAddress a1 = sf::IpAddress::None; // an invalid address (same as a0) +/// sf::IpAddress a2("127.0.0.1"); // the local host address +/// sf::IpAddress a3 = sf::IpAddress::Broadcast; // the broadcast address +/// sf::IpAddress a4(192, 168, 1, 56); // a local address +/// sf::IpAddress a5("my_computer"); // a local address created from a network name +/// sf::IpAddress a6("89.54.1.169"); // a distant address +/// sf::IpAddress a7("www.google.com"); // a distant address created from a network name +/// sf::IpAddress a8 = sf::IpAddress::getLocalAddress(); // my address on the local network +/// sf::IpAddress a9 = sf::IpAddress::getPublicAddress(); // my address on the internet +/// \endcode +/// +/// Note that sf::IpAddress currently doesn't support IPv6 +/// nor other types of network addresses. +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/Packet.hpp b/include/SFML/Network/Packet.hpp index 2d3e201..a400aae 100644 --- a/include/SFML/Network/Packet.hpp +++ b/include/SFML/Network/Packet.hpp @@ -1,407 +1,411 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_PACKET_HPP
-#define SFML_PACKET_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Network/Export.hpp>
-#include <string>
-#include <vector>
-
-
-namespace sf
-{
-class String;
-class TcpSocket;
-class UdpSocket;
-
-////////////////////////////////////////////////////////////
-/// \brief Utility class to build blocks of data to transfer
-/// over the network
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API Packet
-{
- // A bool-like type that cannot be converted to integer or pointer types
- typedef bool (Packet::*BoolType)(std::size_t);
-
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- /// Creates an empty packet.
- ///
- ////////////////////////////////////////////////////////////
- Packet();
-
- ////////////////////////////////////////////////////////////
- /// \brief Virtual destructor
- ///
- ////////////////////////////////////////////////////////////
- virtual ~Packet();
-
- ////////////////////////////////////////////////////////////
- /// \brief Append data to the end of the packet
- ///
- /// \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);
-
- ////////////////////////////////////////////////////////////
- /// \brief Clear the packet
- ///
- /// After calling Clear, the packet is empty.
- ///
- /// \see append
- ///
- ////////////////////////////////////////////////////////////
- void clear();
-
- ////////////////////////////////////////////////////////////
- /// \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 void* getData() const;
-
- ////////////////////////////////////////////////////////////
- /// \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;
-
- ////////////////////////////////////////////////////////////
- /// \brief Tell if the reading position has reached the
- /// end of 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;
-
-public:
-
- ////////////////////////////////////////////////////////////
- /// \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:
- /// \code
- /// float x;
- /// packet >> x;
- /// if (packet)
- /// {
- /// // ok, x was extracted successfully
- /// }
- ///
- /// // -- or --
- ///
- /// float x;
- /// if (packet >> x)
- /// {
- /// // ok, x was extracted successfully
- /// }
- /// \endcode
- ///
- /// Don't focus on the return type, it's equivalent to bool but
- /// it disallows unwanted implicit conversions to integer or
- /// pointer types.
- ///
- /// \return True if last data extraction from packet was successful
- ///
- /// \see endOfPacket
- ///
- ////////////////////////////////////////////////////////////
- operator BoolType() const;
-
- ////////////////////////////////////////////////////////////
- /// Overloads of operator >> to read data from the packet
- ///
- ////////////////////////////////////////////////////////////
- Packet& operator >>(bool& data);
- Packet& operator >>(Int8& data);
- Packet& operator >>(Uint8& data);
- Packet& operator >>(Int16& data);
- Packet& operator >>(Uint16& data);
- Packet& operator >>(Int32& data);
- Packet& operator >>(Uint32& data);
- Packet& operator >>(float& data);
- Packet& operator >>(double& data);
- Packet& operator >>(char* data);
- Packet& operator >>(std::string& data);
- Packet& operator >>(wchar_t* data);
- Packet& operator >>(std::wstring& data);
- Packet& operator >>(String& data);
-
- ////////////////////////////////////////////////////////////
- /// Overloads of operator << to write data into the packet
- ///
- ////////////////////////////////////////////////////////////
- Packet& operator <<(bool data);
- Packet& operator <<(Int8 data);
- Packet& operator <<(Uint8 data);
- Packet& operator <<(Int16 data);
- Packet& operator <<(Uint16 data);
- Packet& operator <<(Int32 data);
- Packet& operator <<(Uint32 data);
- Packet& operator <<(float data);
- Packet& operator <<(double data);
- Packet& operator <<(const char* data);
- Packet& operator <<(const std::string& data);
- Packet& operator <<(const wchar_t* data);
- Packet& operator <<(const std::wstring& data);
- Packet& operator <<(const String& data);
-
-protected:
-
- friend class TcpSocket;
- friend class UdpSocket;
-
- ////////////////////////////////////////////////////////////
- /// \brief Called before the packet is sent over the network
- ///
- /// 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 void* onSend(std::size_t& size);
-
- ////////////////////////////////////////////////////////////
- /// \brief Called after the packet is received over the network
- ///
- /// 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
- ///
- /// \see onSend
- ///
- ////////////////////////////////////////////////////////////
- virtual void onReceive(const void* data, std::size_t size);
-
-private :
-
- ////////////////////////////////////////////////////////////
- /// Disallow comparisons between packets
- ///
- ////////////////////////////////////////////////////////////
- bool operator ==(const Packet& right) const;
- bool operator !=(const Packet& right) const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Check if the packet can extract a given number of bytes
- ///
- /// This function updates accordingly the state of the packet.
- ///
- /// \param size Size to check
- ///
- /// \return True if \a size bytes can be read from the packet
- ///
- ////////////////////////////////////////////////////////////
- bool checkSize(std::size_t size);
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- std::vector<char> m_data; ///< Data stored in the packet
- std::size_t m_readPos; ///< Current reading position in the packet
- bool m_isValid; ///< Reading state of the packet
-};
-
-} // namespace sf
-
-
-#endif // SFML_PACKET_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::Packet
-/// \ingroup network
-///
-/// 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:
-/// \code
-/// 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.
-///
-/// \code
-/// 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:
-/// \code
-/// class ZipPacket : public sf::Packet
-/// {
-/// virtual const void* onSend(std::size_t& size)
-/// {
-/// const void* srcData = getData();
-/// std::size_t srcSize = getDataSize();
-///
-/// return MySuperZipFunction(srcData, srcSize, &size);
-/// }
-///
-/// virtual void onReceive(const void* data, std::size_t size)
-/// {
-/// std::size_t dstSize;
-/// const void* dstData = MySuperUnzipFunction(data, size, &dstSize);
-///
-/// append(dstData, dstSize);
-/// }
-/// };
-///
-/// // Use like regular packets:
-/// ZipPacket packet;
-/// packet << x << s << d;
-/// ...
-/// \endcode
-///
-/// \see sf::TcpSocket, sf::UdpSocket
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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_PACKET_HPP +#define SFML_PACKET_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Export.hpp> +#include <string> +#include <vector> + + +namespace sf +{ +class String; +class TcpSocket; +class UdpSocket; + +//////////////////////////////////////////////////////////// +/// \brief Utility class to build blocks of data to transfer +/// over the network +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API Packet +{ + // A bool-like type that cannot be converted to integer or pointer types + typedef bool (Packet::*BoolType)(std::size_t); + +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates an empty packet. + /// + //////////////////////////////////////////////////////////// + Packet(); + + //////////////////////////////////////////////////////////// + /// \brief Virtual destructor + /// + //////////////////////////////////////////////////////////// + virtual ~Packet(); + + //////////////////////////////////////////////////////////// + /// \brief Append data to the end of the packet + /// + /// \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); + + //////////////////////////////////////////////////////////// + /// \brief Clear the packet + /// + /// After calling Clear, the packet is empty. + /// + /// \see append + /// + //////////////////////////////////////////////////////////// + void clear(); + + //////////////////////////////////////////////////////////// + /// \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 void* getData() const; + + //////////////////////////////////////////////////////////// + /// \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; + + //////////////////////////////////////////////////////////// + /// \brief Tell if the reading position has reached the + /// end of 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; + +public: + + //////////////////////////////////////////////////////////// + /// \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 behavior is the same as standard C++ streams. + /// + /// Usage example: + /// \code + /// float x; + /// packet >> x; + /// if (packet) + /// { + /// // ok, x was extracted successfully + /// } + /// + /// // -- or -- + /// + /// float x; + /// if (packet >> x) + /// { + /// // ok, x was extracted successfully + /// } + /// \endcode + /// + /// Don't focus on the return type, it's equivalent to bool but + /// it disallows unwanted implicit conversions to integer or + /// pointer types. + /// + /// \return True if last data extraction from packet was successful + /// + /// \see endOfPacket + /// + //////////////////////////////////////////////////////////// + operator BoolType() const; + + //////////////////////////////////////////////////////////// + /// Overloads of operator >> to read data from the packet + /// + //////////////////////////////////////////////////////////// + Packet& operator >>(bool& data); + Packet& operator >>(Int8& data); + Packet& operator >>(Uint8& data); + Packet& operator >>(Int16& data); + Packet& operator >>(Uint16& data); + Packet& operator >>(Int32& data); + Packet& operator >>(Uint32& data); + Packet& operator >>(Int64& data); + Packet& operator >>(Uint64& data); + Packet& operator >>(float& data); + Packet& operator >>(double& data); + Packet& operator >>(char* data); + Packet& operator >>(std::string& data); + Packet& operator >>(wchar_t* data); + Packet& operator >>(std::wstring& data); + Packet& operator >>(String& data); + + //////////////////////////////////////////////////////////// + /// Overloads of operator << to write data into the packet + /// + //////////////////////////////////////////////////////////// + Packet& operator <<(bool data); + Packet& operator <<(Int8 data); + Packet& operator <<(Uint8 data); + Packet& operator <<(Int16 data); + Packet& operator <<(Uint16 data); + Packet& operator <<(Int32 data); + Packet& operator <<(Uint32 data); + Packet& operator <<(Int64 data); + Packet& operator <<(Uint64 data); + Packet& operator <<(float data); + Packet& operator <<(double data); + Packet& operator <<(const char* data); + Packet& operator <<(const std::string& data); + Packet& operator <<(const wchar_t* data); + Packet& operator <<(const std::wstring& data); + Packet& operator <<(const String& data); + +protected: + + friend class TcpSocket; + friend class UdpSocket; + + //////////////////////////////////////////////////////////// + /// \brief Called before the packet is sent over the network + /// + /// 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 void* onSend(std::size_t& size); + + //////////////////////////////////////////////////////////// + /// \brief Called after the packet is received over the network + /// + /// This function can be defined by derived classes to + /// transform the data after it is received; this can be + /// used for decompression, 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 + /// + /// \see onSend + /// + //////////////////////////////////////////////////////////// + virtual void onReceive(const void* data, std::size_t size); + +private: + + //////////////////////////////////////////////////////////// + /// Disallow comparisons between packets + /// + //////////////////////////////////////////////////////////// + bool operator ==(const Packet& right) const; + bool operator !=(const Packet& right) const; + + //////////////////////////////////////////////////////////// + /// \brief Check if the packet can extract a given number of bytes + /// + /// This function updates accordingly the state of the packet. + /// + /// \param size Size to check + /// + /// \return True if \a size bytes can be read from the packet + /// + //////////////////////////////////////////////////////////// + bool checkSize(std::size_t size); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::vector<char> m_data; ///< Data stored in the packet + std::size_t m_readPos; ///< Current reading position in the packet + bool m_isValid; ///< Reading state of the packet +}; + +} // namespace sf + + +#endif // SFML_PACKET_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Packet +/// \ingroup network +/// +/// 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 +/// transferring 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 behavior 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: +/// \code +/// 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. +/// +/// \code +/// 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: +/// \code +/// class ZipPacket : public sf::Packet +/// { +/// virtual const void* onSend(std::size_t& size) +/// { +/// const void* srcData = getData(); +/// std::size_t srcSize = getDataSize(); +/// +/// return MySuperZipFunction(srcData, srcSize, &size); +/// } +/// +/// virtual void onReceive(const void* data, std::size_t size) +/// { +/// std::size_t dstSize; +/// const void* dstData = MySuperUnzipFunction(data, size, &dstSize); +/// +/// append(dstData, dstSize); +/// } +/// }; +/// +/// // Use like regular packets: +/// ZipPacket packet; +/// packet << x << s << d; +/// ... +/// \endcode +/// +/// \see sf::TcpSocket, sf::UdpSocket +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/Socket.hpp b/include/SFML/Network/Socket.hpp index 4b30307..8b66453 100644 --- a/include/SFML/Network/Socket.hpp +++ b/include/SFML/Network/Socket.hpp @@ -1,218 +1,218 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/Export.hpp>
-#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_NETWORK_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 in 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 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();
-
-private :
-
- friend class SocketSelector;
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- Type m_type; ///< Type of the socket (TCP or UDP)
- SocketHandle m_socket; ///< Socket descriptor
- bool m_isBlocking; ///< Current blocking mode of the socket
-};
-
-} // namespace sf
-
-
-#endif // SFML_SOCKET_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::Socket
-/// \ingroup network
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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/Export.hpp> +#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_NETWORK_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 in 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 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(); + +private: + + friend class SocketSelector; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Type m_type; ///< Type of the socket (TCP or UDP) + SocketHandle m_socket; ///< Socket descriptor + bool m_isBlocking; ///< Current blocking mode of the socket +}; + +} // namespace sf + + +#endif // SFML_SOCKET_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Socket +/// \ingroup network +/// +/// 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 +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/SocketHandle.hpp b/include/SFML/Network/SocketHandle.hpp index 8edd46a..83c2422 100644 --- a/include/SFML/Network/SocketHandle.hpp +++ b/include/SFML/Network/SocketHandle.hpp @@ -1,57 +1,57 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_SOCKETHANDLE_HPP
-#define SFML_SOCKETHANDLE_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-
-#if defined(SFML_SYSTEM_WINDOWS)
- #include <basetsd.h>
-#endif
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-// 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
-
-
-#endif // SFML_SOCKETHANDLE_HPP
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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_SOCKETHANDLE_HPP +#define SFML_SOCKETHANDLE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Config.hpp> + +#if defined(SFML_SYSTEM_WINDOWS) + #include <basetsd.h> +#endif + + +namespace sf +{ +//////////////////////////////////////////////////////////// +// 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 + + +#endif // SFML_SOCKETHANDLE_HPP diff --git a/include/SFML/Network/SocketSelector.hpp b/include/SFML/Network/SocketSelector.hpp index 414a941..336b301 100644 --- a/include/SFML/Network/SocketSelector.hpp +++ b/include/SFML/Network/SocketSelector.hpp @@ -1,263 +1,263 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/Network/Export.hpp>
-#include <SFML/System/Time.hpp>
-
-
-namespace sf
-{
-class Socket;
-
-////////////////////////////////////////////////////////////
-/// \brief Multiplexer that allows to read from multiple sockets
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_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.
- /// This function does nothing if the socket is not valid.
- ///
- /// \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.
- ///
- /// \param timeout Maximum time to wait, (use Time::Zero for infinity)
- ///
- /// \return True if there are sockets ready, false otherwise
- ///
- /// \see isReady
- ///
- ////////////////////////////////////////////////////////////
- bool wait(Time timeout = Time::Zero);
-
- ////////////////////////////////////////////////////////////
- /// \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.
- ///
- /// \param socket Socket to test
- ///
- /// \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* m_impl; ///< Opaque pointer to the implementation (which requires OS-specific types)
-};
-
-} // namespace sf
-
-
-#endif // SFML_SOCKETSELECTOR_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::SocketSelector
-/// \ingroup network
-///
-/// 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
-/// {
-/// // Error, we won't get a new connection, delete the socket
-/// delete 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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/Network/Export.hpp> +#include <SFML/System/Time.hpp> + + +namespace sf +{ +class Socket; + +//////////////////////////////////////////////////////////// +/// \brief Multiplexer that allows to read from multiple sockets +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_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. + /// This function does nothing if the socket is not valid. + /// + /// \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. + /// + /// \param timeout Maximum time to wait, (use Time::Zero for infinity) + /// + /// \return True if there are sockets ready, false otherwise + /// + /// \see isReady + /// + //////////////////////////////////////////////////////////// + bool wait(Time timeout = Time::Zero); + + //////////////////////////////////////////////////////////// + /// \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. + /// + /// \param socket Socket to test + /// + /// \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* m_impl; ///< Opaque pointer to the implementation (which requires OS-specific types) +}; + +} // namespace sf + + +#endif // SFML_SOCKETSELECTOR_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::SocketSelector +/// \ingroup network +/// +/// 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 outside 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 +/// { +/// // Error, we won't get a new connection, delete the socket +/// delete 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 +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/TcpListener.hpp b/include/SFML/Network/TcpListener.hpp index 5a5bdb3..db93a6c 100644 --- a/include/SFML/Network/TcpListener.hpp +++ b/include/SFML/Network/TcpListener.hpp @@ -1,162 +1,162 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/Export.hpp>
-#include <SFML/Network/Socket.hpp>
-
-
-namespace sf
-{
-class TcpSocket;
-
-////////////////////////////////////////////////////////////
-/// \brief Socket that listens to new TCP connections
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API TcpListener : public Socket
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- ////////////////////////////////////////////////////////////
- TcpListener();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the port to which the socket is bound locally
- ///
- /// If the socket is not listening to a port, this function
- /// returns 0.
- ///
- /// \return Port to which the socket is bound
- ///
- /// \see listen
- ///
- ////////////////////////////////////////////////////////////
- unsigned short getLocalPort() const;
-
- ////////////////////////////////////////////////////////////
- /// \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 Stop listening and close the socket
- ///
- /// This function gracefully stops the listener. If the
- /// socket is not listening, this function has no effect.
- ///
- /// \see listen
- ///
- ////////////////////////////////////////////////////////////
- void close();
-
- ////////////////////////////////////////////////////////////
- /// \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
-/// \ingroup network
-///
-/// 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, you must call accept and
-/// the listener 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.
-///
-/// A listener is automatically closed on destruction, like all
-/// other types of socket. However if you want to stop listening
-/// before the socket is destroyed, you can call its close()
-/// function.
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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/Export.hpp> +#include <SFML/Network/Socket.hpp> + + +namespace sf +{ +class TcpSocket; + +//////////////////////////////////////////////////////////// +/// \brief Socket that listens to new TCP connections +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API TcpListener : public Socket +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + TcpListener(); + + //////////////////////////////////////////////////////////// + /// \brief Get the port to which the socket is bound locally + /// + /// If the socket is not listening to a port, this function + /// returns 0. + /// + /// \return Port to which the socket is bound + /// + /// \see listen + /// + //////////////////////////////////////////////////////////// + unsigned short getLocalPort() const; + + //////////////////////////////////////////////////////////// + /// \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 Stop listening and close the socket + /// + /// This function gracefully stops the listener. If the + /// socket is not listening, this function has no effect. + /// + /// \see listen + /// + //////////////////////////////////////////////////////////// + void close(); + + //////////////////////////////////////////////////////////// + /// \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 +/// \ingroup network +/// +/// 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, you must call accept and +/// the listener 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. +/// +/// A listener is automatically closed on destruction, like all +/// other types of socket. However if you want to stop listening +/// before the socket is destroyed, you can call its close() +/// function. +/// +/// 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 +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/TcpSocket.hpp b/include/SFML/Network/TcpSocket.hpp index 2db2b72..03a69ec 100644 --- a/include/SFML/Network/TcpSocket.hpp +++ b/include/SFML/Network/TcpSocket.hpp @@ -1,292 +1,292 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/Export.hpp>
-#include <SFML/Network/Socket.hpp>
-#include <SFML/System/Time.hpp>
-
-
-namespace sf
-{
-class TcpListener;
-class IpAddress;
-class Packet;
-
-////////////////////////////////////////////////////////////
-/// \brief Specialized socket using the TCP protocol
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_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
- ///
- /// \return Status code
- ///
- /// \see disconnect
- ///
- ////////////////////////////////////////////////////////////
- Status connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero);
-
- ////////////////////////////////////////////////////////////
- /// \brief Disconnect the socket 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 void* 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(void* 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);
-
-private:
-
- friend class TcpListener;
-
- ////////////////////////////////////////////////////////////
- /// \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
- };
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- PendingPacket m_pendingPacket; ///< Temporary data of the packet currently being received
-};
-
-} // namespace sf
-
-
-#endif // SFML_TCPSOCKET_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::TcpSocket
-/// \ingroup network
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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/Export.hpp> +#include <SFML/Network/Socket.hpp> +#include <SFML/System/Time.hpp> + + +namespace sf +{ +class TcpListener; +class IpAddress; +class Packet; + +//////////////////////////////////////////////////////////// +/// \brief Specialized socket using the TCP protocol +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_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 + /// + /// \return Status code + /// + /// \see disconnect + /// + //////////////////////////////////////////////////////////// + Status connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero); + + //////////////////////////////////////////////////////////// + /// \brief Disconnect the socket 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 void* 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(void* 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); + +private: + + friend class TcpListener; + + //////////////////////////////////////////////////////////// + /// \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 + }; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + PendingPacket m_pendingPacket; ///< Temporary data of the packet currently being received +}; + +} // namespace sf + + +#endif // SFML_TCPSOCKET_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::TcpSocket +/// \ingroup network +/// +/// 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 explicitly 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 +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Network/UdpSocket.hpp b/include/SFML/Network/UdpSocket.hpp index e5fa3b0..268edd0 100644 --- a/include/SFML/Network/UdpSocket.hpp +++ b/include/SFML/Network/UdpSocket.hpp @@ -1,283 +1,283 @@ -////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/Export.hpp>
-#include <SFML/Network/Socket.hpp>
-#include <vector>
-
-
-namespace sf
-{
-class IpAddress;
-class Packet;
-
-////////////////////////////////////////////////////////////
-/// \brief Specialized socket using the UDP protocol
-///
-////////////////////////////////////////////////////////////
-class SFML_NETWORK_API UdpSocket : public Socket
-{
-public :
-
- ////////////////////////////////////////////////////////////
- // Constants
- ////////////////////////////////////////////////////////////
- enum
- {
- MaxDatagramSize = 65507 ///< The maximum number of bytes that can be sent in a single UDP datagram
- };
-
- ////////////////////////////////////////////////////////////
- /// \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
- ///
- /// Make sure that \a size is not greater than
- /// UdpSocket::MaxDatagramSize, otherwise this function will
- /// fail and no data will be sent.
- ///
- /// \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 void* 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.
- /// Be careful to use a buffer which is large enough for
- /// the data that you intend to receive, if it is too small
- /// then an error will be returned and *all* the data will
- /// be lost.
- ///
- /// \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(void* 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
- ///
- /// Make sure that the packet size is not greater than
- /// UdpSocket::MaxDatagramSize, otherwise this function will
- /// fail and no data will be sent.
- ///
- /// \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);
-
-private:
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- std::vector<char> m_buffer; ///< Temporary buffer holding the received data in Receive(Packet)
-};
-
-} // namespace sf
-
-
-#endif // SFML_UDPSOCKET_HPP
-
-
-////////////////////////////////////////////////////////////
-/// \class sf::UdpSocket
-/// \ingroup network
-///
-/// 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.
-///
-/// It is a datagram protocol: bounded blocks of data (datagrams)
-/// are transfered over the network rather than a continuous
-/// stream of data (TCP). Therefore, one call to send will always
-/// match one call to receive (if the datagram is not lost),
-/// with the same data that was sent.
-///
-/// The UDP protocol is lightweight but unreliable. Unreliable
-/// means that datagrams may be duplicated, be lost or
-/// arrive reordered. However, if a datagram arrives, its
-/// data is guaranteed to be valid.
-///
-/// UDP is generally used for real-time communication
-/// (audio or video streaming, real-time games, etc.) where
-/// speed is crucial and lost 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, whereas 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.
-///
-/// It is important to note that UdpSocket is unable to send
-/// datagrams bigger than MaxDatagramSize. In this case, it
-/// returns an error and doesn't send anything. This applies
-/// to both raw data and packets. Indeed, even packets are
-/// unable to split and recompose data, due to the unreliability
-/// of the protocol (dropped, mixed or duplicated datagrams may
-/// lead to a big mess when trying to recompose a packet).
-///
-/// 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
-///
-////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2014 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/Export.hpp> +#include <SFML/Network/Socket.hpp> +#include <vector> + + +namespace sf +{ +class IpAddress; +class Packet; + +//////////////////////////////////////////////////////////// +/// \brief Specialized socket using the UDP protocol +/// +//////////////////////////////////////////////////////////// +class SFML_NETWORK_API UdpSocket : public Socket +{ +public: + + //////////////////////////////////////////////////////////// + // Constants + //////////////////////////////////////////////////////////// + enum + { + MaxDatagramSize = 65507 ///< The maximum number of bytes that can be sent in a single UDP datagram + }; + + //////////////////////////////////////////////////////////// + /// \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 + /// + /// Make sure that \a size is not greater than + /// UdpSocket::MaxDatagramSize, otherwise this function will + /// fail and no data will be sent. + /// + /// \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 void* 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. + /// Be careful to use a buffer which is large enough for + /// the data that you intend to receive, if it is too small + /// then an error will be returned and *all* the data will + /// be lost. + /// + /// \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(void* 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 + /// + /// Make sure that the packet size is not greater than + /// UdpSocket::MaxDatagramSize, otherwise this function will + /// fail and no data will be sent. + /// + /// \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); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::vector<char> m_buffer; ///< Temporary buffer holding the received data in Receive(Packet) +}; + +} // namespace sf + + +#endif // SFML_UDPSOCKET_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::UdpSocket +/// \ingroup network +/// +/// 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. +/// +/// It is a datagram protocol: bounded blocks of data (datagrams) +/// are transfered over the network rather than a continuous +/// stream of data (TCP). Therefore, one call to send will always +/// match one call to receive (if the datagram is not lost), +/// with the same data that was sent. +/// +/// The UDP protocol is lightweight but unreliable. Unreliable +/// means that datagrams may be duplicated, be lost or +/// arrive reordered. However, if a datagram arrives, its +/// data is guaranteed to be valid. +/// +/// UDP is generally used for real-time communication +/// (audio or video streaming, real-time games, etc.) where +/// speed is crucial and lost 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, whereas 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. +/// +/// It is important to note that UdpSocket is unable to send +/// datagrams bigger than MaxDatagramSize. In this case, it +/// returns an error and doesn't send anything. This applies +/// to both raw data and packets. Indeed, even packets are +/// unable to split and recompose data, due to the unreliability +/// of the protocol (dropped, mixed or duplicated datagrams may +/// lead to a big mess when trying to recompose a packet). +/// +/// 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 explicitly 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 +/// +//////////////////////////////////////////////////////////// |