Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: NetRelais TCP_Client_Example TCP_Server_Example UDP_Server_Example ... more
tcp/socket.cpp
- Committer:
- NegativeBlack
- Date:
- 2012-07-18
- Revision:
- 3:d30db8752485
- Parent:
- 0:00d5bc4b46e1
- Child:
- 4:d854fa394f85
File content as of revision 3:d30db8752485:
/** * Copyright (c) 2012, Roy van Dam <roy@vandam-innovations.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "socket.hpp" using namespace network::tcp; int Socket::open() { // Check socket status if (this->_status != Socket::Closed) { return -1; } // Open socket this->_socket = ::socket(AF_INET, SOCK_STREAM, 0); if (this->_socket < 0) { return -1; } // Update status and return this->_status = Socket::Open; return 0; } int Socket::connect(ip::Address &address, int port) { ip::Endpoint endpoint(address, port); return this->connect(endpoint); } int Socket::connect(ip::Endpoint &endpoint) { // Check socket status if ((this->_status != Socket::Open) || (this->_status != Socket::Disconnected)) { return -1; } // Create native endpoint struct sockaddr_in native_endpoint; endpoint.toNative(&native_endpoint); // Attempt to connect with remote endpoint. int result = ::connect(this->_socket, (const struct sockaddr *)&native_endpoint, sizeof(native_endpoint)); // Check result if (result < 0) { return -1; } // Update remote endpoint information. this->_remote_endpoint = endpoint; // Update status and return this->_status = Socket::Connected; return 0; } int Socket::shutdown() { // Check socket status if (this->_status != Socket::Connected) { return -1; } // Attempt to shutdown the connection. int result = ::shutdown(this->_socket, SHUT_RDWR); if (result < 0) { return -1; } // Update status and return this->_status = Socket::Disconnected; return 0; } int Socket::listen(int max_pending) { // Check socket status if (this->_status != Socket::Open) { return -1; } // Put socket into listening mode. int result = ::listen(this->_socket, max_pending); if (result < 0) { return -1; } // Update status and return this->_status = Socket::Listening; return 0; } int Socket::accept(Socket &client) { // Check socket status if (this->_status != Socket::Listening) { return -1; } // Check client socket status if (client._status != Socket::Closed) { return -1; } // Create native endpoint struct sockaddr_in native_endpoint; int native_endpoint_size = sizeof(native_endpoint); std::memset(&native_endpoint, 0, sizeof(native_endpoint)); // Accept new (pending) connections. int socket = ::accept(this->_socket, (struct sockaddr*)&native_endpoint, (u32_t *)&native_endpoint_size); // Did we succeed? if (socket < 0) { return -1; } // Check if we received the endpoint information correctly. if (native_endpoint_size != sizeof(native_endpoint)) { printf("Warning: invalid endpoint size received\n\r"); } // Populate client socket client._socket = socket; client._status = Socket::Connected; client._remote_endpoint.fromNative(&native_endpoint); return 0; } int Socket::write(void *data, size_t size) { // Check data buffer and size if (data == NULL || size == 0) { return -1; } // Check socket status if (this->_status != Socket::Connected) { return -1; } // Update status this->_status = Socket::Sending; // Try to send the specified amount of bytes. int bytes_written = ::send(this->_socket, data, size, 0); // Update status this->_status = (bytes_written == 0) ? Socket::Disconnected : Socket::Connected; // Return the result. return bytes_written; } int Socket::read(void *data, size_t max_size) { // Check data buffer and size if (data == NULL || max_size == 0) { return -1; } // Check socket status if (this->_status != Socket::Connected) { return -1; } // Update status this->_status = Socket::Receiving; // Try to read data from the socket. int bytes_read = ::recv(this->_socket, data, max_size, 0); // Update status this->_status = (bytes_read == 0) ? Socket::Disconnected : Socket::Connected; // Return bytes read return bytes_read; }