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: SimpleSocketExamples 1.0
ClientSocket.cpp
00001 /* 00002 Copyright (c) 2011, Senio Networks, Inc. 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #include "SimpleSocket.h" 00024 #include <stdarg.h> 00025 00026 ClientSocket::ClientSocket(IpAddr ip, TCPSocket *socket, bool debug) 00027 : ip(ip), socket(socket), readable(true), writable(true), preread(-1), 00028 state(CONNECTED), debug(debug) { 00029 if (socket) 00030 socket->setOnEvent(this, &ClientSocket::onTCPSocketEvent); 00031 } 00032 00033 ClientSocket::ClientSocket(IpAddr ip, int port, float timeout, bool debug) 00034 : readable(true), writable(true), preread(-1), debug(debug) { 00035 createClientSocket(ip, port, timeout); 00036 } 00037 00038 ClientSocket::ClientSocket(char *hostname, int port, float timeout, bool debug) 00039 : readable(true), writable(true), preread(-1), debug(debug) { 00040 Resolver resolver; 00041 createClientSocket(resolver.resolve(hostname, debug), port, timeout); 00042 } 00043 00044 ClientSocket::ClientSocket(const ClientSocket& that) { 00045 *this = that; 00046 ::printf("cc called\n"); 00047 } 00048 00049 void ClientSocket::createClientSocket(IpAddr ip, int port, float timeout) { 00050 this->ip = ip; 00051 socket = new TCPSocket(); 00052 socket->setOnEvent(this, &ClientSocket::onTCPSocketEvent); 00053 SocketError err = socket->connect(Host(ip, port)); 00054 if (!err) { 00055 Timer timer; 00056 timer.start(); 00057 state = CONNECTING; 00058 while (state == CONNECTING && timer.read() < timeout) { 00059 Net::poll(); 00060 if (state == CONNECTED) 00061 return; 00062 wait_us(100); 00063 } 00064 } else 00065 DBG(SocketError(err)); 00066 00067 writable = false; 00068 state = DISCONNECTED; 00069 socket->resetOnEvent(); 00070 socket->close(); 00071 delete socket; 00072 socket = 0; 00073 } 00074 00075 IpAddr ClientSocket::getIp() { 00076 return ip; 00077 } 00078 00079 bool ClientSocket::connected() { 00080 if (socket) 00081 Net::poll(); 00082 00083 if (!readable && state == DISCONNECTED) 00084 close(); 00085 00086 return socket != 0; 00087 } 00088 00089 bool ClientSocket::available() { 00090 if (preread != -1) 00091 return true; 00092 00093 if (!readable) 00094 Net::poll(); 00095 00096 if (readable) { 00097 char c; 00098 int ret = socket->recv(&c, 1); 00099 if (ret > 0) { 00100 preread = c; 00101 return true; 00102 } else 00103 readable = false; 00104 } 00105 00106 if (!readable && state == DISCONNECTED) 00107 close(); 00108 00109 return false; 00110 } 00111 00112 void ClientSocket::onTCPSocketEvent(TCPSocketEvent e) { 00113 DBG(SocketEvent(e)); 00114 00115 switch (e) { 00116 case TCPSOCKET_CONNECTED: 00117 state = CONNECTED; 00118 break; 00119 case TCPSOCKET_READABLE: 00120 readable = true; 00121 break; 00122 case TCPSOCKET_WRITEABLE: 00123 writable = true; 00124 break; 00125 case TCPSOCKET_DISCONNECTED: 00126 state = DISCONNECTED; 00127 break; 00128 } 00129 } 00130 00131 int ClientSocket::read() { 00132 char c; 00133 00134 if (preread != -1) { 00135 c = preread & 255; 00136 preread = -1; 00137 return c; 00138 } 00139 00140 int ret = socket->recv(&c, 1); 00141 if (ret > 0) { 00142 return (int) c & 255; 00143 } else { 00144 readable = false; 00145 return -1; 00146 } 00147 } 00148 00149 int ClientSocket::read(char *buf, int size) { 00150 int req = size; 00151 00152 if (preread != -1 && size > 0) { 00153 *buf++ = preread & 255; 00154 preread = -1; 00155 req--; 00156 } 00157 00158 while (req > 0) { 00159 int got = socket->recv(buf, req); 00160 if (got > 0) { 00161 buf += got; 00162 req -= got; 00163 } else { 00164 readable = false; 00165 break; 00166 } 00167 } 00168 00169 return size - req; 00170 } 00171 00172 int ClientSocket::scanf(const char* format, ...) { 00173 va_list argp; 00174 va_start(argp, format); 00175 char buf[256]; 00176 00177 int len = read(buf, sizeof(buf) - 1); 00178 if (len <= 0) 00179 return 0; 00180 buf[len] = '\0'; 00181 00182 int ret = vsscanf(buf, format, argp); 00183 va_end(argp); 00184 return ret; 00185 } 00186 00187 int ClientSocket::write(char c) { 00188 return write(&c, 1); 00189 } 00190 00191 int ClientSocket::write(char *buf, int size) { 00192 int ret = socket->send(buf, size); 00193 if (ret > 0) { 00194 return ret; 00195 } else { 00196 writable = false; 00197 return -1; 00198 } 00199 } 00200 00201 int ClientSocket::printf(const char* format, ...) { 00202 va_list argp; 00203 va_start(argp, format); 00204 char buf[256]; 00205 00206 int len = vsnprintf(buf, sizeof(buf), format, argp); 00207 va_end(argp); 00208 return write(buf, len); 00209 } 00210 00211 void ClientSocket::close() { 00212 if (socket) { 00213 readable = false; 00214 writable = false; 00215 socket->resetOnEvent(); 00216 socket->close(); 00217 delete socket; 00218 socket = 0; 00219 } 00220 } 00221 00222 ClientSocket::operator bool() { 00223 return connected(); 00224 } 00225 00226 void ClientSocket::setDebug(bool debug) { 00227 this->debug = debug; 00228 }
Generated on Sat Jul 23 2022 06:16:20 by
 1.7.2
 1.7.2