00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ntcpsocket.h"
00023
00024 NTcpSocket::NTcpSocket(void)
00025 : NAbstractSocket(),
00026 m_addr(),
00027 m_sock(-1)
00028 {
00029 init();
00030 }
00031
00032 NTcpSocket::NTcpSocket(NHostAddress &host)
00033 : NAbstractSocket(host),
00034 m_addr(),
00035 m_sock(-1)
00036 {
00037 init();
00038 }
00039
00040
00041 NTcpSocket::NTcpSocket(const NString &host, nuint16 port)
00042 : NAbstractSocket(host, port),
00043 m_addr(),
00044 m_sock(-1)
00045 {
00046 init();
00047 }
00048
00049 NTcpSocket::NTcpSocket(nuint16 timeout, nint32 sock, struct sockaddr_in client)
00050 : NAbstractSocket(),
00051 m_addr(),
00052 m_sock(sock)
00053 {
00054 init();
00055 setTimeout(timeout);
00056 m_addr = client;
00057
00058 m_host.setAddress(reinterpret_cast<struct sockaddr *>(&m_addr));
00059 setPort(ntohs(m_addr.sin_port));
00060 }
00061
00062 NTcpSocket::~NTcpSocket(void) {
00063
00064 }
00065
00066 void NTcpSocket::setPort(nint16 port) {
00067 NAbstractSocket::setPort(port);
00068
00069 m_addr.sin_port = htons(m_port);
00070 }
00071
00072 void NTcpSocket::setSocketOptions(nint32 opt) {
00073 int val = 1;
00074
00075 NAbstractSocket::setSocketOptions(opt);
00076
00077
00078
00079 if (m_opt & REUSE_ADDRESS) {
00080 setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
00081 }
00082
00083
00084 if (m_opt & KEEPALIVE) {
00085 setsockopt(m_sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
00086 }
00087 }
00088
00089
00090 void NTcpSocket::init(void) {
00091 memset(&m_addr, 0, sizeof(m_addr));
00092
00093 m_addr.sin_family = AF_INET;
00094 }
00095
00096 void NTcpSocket::open(void) {
00097 m_sock = socket(PF_INET, SOCK_STREAM, 0);
00098 if (!m_sock == -1) {
00099 throw NNetworkException(nerror(errno), "", NException::NETWORK,
00100 NNetworkException::SOCKET_INIT_FAILED);
00101 }
00102
00103 }
00104
00105 void NTcpSocket::closeDevice(void) {
00106 disconnectFromHost();
00107 }
00108
00109 void NTcpSocket::disconnectFromHost(void) {
00110 close(m_sock);
00111 m_sock = 0;
00112 }
00113
00114 void NTcpSocket::connectToHost() {
00115 int ret = 0;
00116
00117 m_host.resolve();
00118 inet_aton(m_host.toString().toChar(), &m_addr.sin_addr);
00119 if (m_addr.sin_addr.s_addr == INADDR_NONE) {
00120 throw NNetworkException("Bad Address", m_host.toString(),
00121 NException::NETWORK, NNetworkException::SOCKET_INIT_FAILED);
00122 }
00123
00124 ret = connect(m_sock, reinterpret_cast<struct sockaddr *>(&m_addr),
00125 sizeof(m_addr));
00126 if (ret == -1) {
00127 NString msg = nerror(errno);
00128
00129 msg += NSTR(": ") + m_host.toString() + NSTR(":") + NString::number(m_port);
00130 throw NNetworkException(msg, m_host.toString(),
00131 NException::NETWORK, NNetworkException::CONNECTION_FAILED);
00132 }
00133 }
00134
00135 void NTcpSocket::execBind(void) {
00136 int ret = 0;
00137
00138 if (m_host.isNull()) {
00139 m_addr.sin_addr.s_addr = INADDR_ANY;
00140 }
00141 else {
00142 m_addr.sin_addr.s_addr = inet_addr(m_host.toString().toChar());
00143 if (m_addr.sin_addr.s_addr == INADDR_NONE) {
00144 throw NNetworkException("Bad Address", m_host.toString(),
00145 NException::NETWORK, NNetworkException::SOCKET_INIT_FAILED);
00146 }
00147 }
00148
00149 ret = bind(m_sock, reinterpret_cast<const struct sockaddr *>(&m_addr),
00150 sizeof(m_addr));
00151 if (ret == -1) {
00152 NString msg = nerror(errno);
00153
00154 msg += NSTR(": ") + m_host.toString() + NSTR(":") + NString::number(m_port);
00155 throw NNetworkException(msg, m_host.toString(), NException::NETWORK,
00156 NNetworkException::SOCKET_INIT_FAILED);
00157 }
00158 }
00159
00160
00161 void NTcpSocket::setPeer(struct sockaddr_in addr) {
00162 m_addr = addr;
00163 }
00164
00165
00166 void NTcpSocket::setSock(int sock) {
00167 m_sock = sock;
00168 }
00169
00170 void NTcpSocket::setupNewSocket(NTcpSocket *sock, struct sockaddr_in addr) {
00171 assert(sock);
00172
00173 sock->setTimeout(m_timeout);
00174 sock->setReadBufferSize(m_readBufferSize);
00175 sock->setHost(m_host);
00176 }
00177
00178
00179 void NTcpSocket::execListen(void) {
00180 int ret = 0;
00181
00182 execBind();
00183 ret = listen(m_sock, m_maxPendingConn);
00184 if (ret == -1) {
00185 NString msg = nerror(errno);
00186
00187 msg += NSTR(": ") + m_host.toString() + NSTR(":") + NString::number(m_port);
00188 throw NException(msg , NException::NETWORK);
00189 }
00190
00191 }
00192
00193
00194 NTcpSocket *NTcpSocket::waitForConnected(void) {
00195 int client = 0;
00196 NTcpSocket *ret = NULL;
00197 struct sockaddr_in cli_addr;
00198 socklen_t len_inet = 0;
00199
00200 len_inet = sizeof(cli_addr);
00201 client = accept(m_sock, reinterpret_cast<struct sockaddr *>(&cli_addr),
00202 &len_inet);
00203 if (client == -1) {
00204 delete ret;
00205 NString msg = nerror(errno);
00206
00207 msg += NSTR(": ") + m_host.toString() + NSTR(":") + NString::number(m_port);
00208 throw NNetworkException(msg , m_host.toString(),
00209 NException::NETWORK, NNetworkException::SOCKET_INIT_FAILED);
00210 }
00211
00212 ret = new NTcpSocket(m_timeout, client, cli_addr);
00213 return ret;
00214
00215 }
00216
00217
00218 NHostAddress NTcpSocket::peerAddress(void) const {
00219 NHostAddress ret;
00220
00221 ret.setAddress(reinterpret_cast<const struct sockaddr *>(&m_addr));
00222 return ret;
00223 }
00224
00225
00226 NString NTcpSocket::peerName(void) const {
00227 return peerAddress().toString();
00228 }
00229
00230
00231 nuint16 NTcpSocket::peerPort(void) const {
00232 return ntohs(m_addr.sin_port);
00233 }
00234
00235
00236 nint32 NTcpSocket::read(NDataStream *buffer) {
00237 nint32 bread = 0;
00238 fd_set fd;
00239 timeval timeout;
00240 nint32 sel = 0;
00241 socklen_t len = 0;
00242 nint32 numRead = -1;
00243 char tmp[m_readBufferSize];
00244
00245 FD_ZERO(&fd);
00246 FD_SET(m_sock, &fd);
00247
00248 timeout.tv_sec = m_timeout;
00249 timeout.tv_usec = 0;
00250
00251 sel = select(m_sock + 1, &fd, NULL, NULL, &timeout);
00252 if (sel < 0) {
00253 throw NNetworkException(nerror(errno), m_host.toString(),
00254 NException::NETWORK, NNetworkException::SOCK_ERROR);
00255 }
00256
00257 if (sel == 0) {
00258 return 0;
00259 }
00260
00261 *buffer = "";
00262 do {
00263 memset(tmp, 0, sizeof(tmp));
00264
00265 numRead = recvfrom(m_sock, &tmp, sizeof(tmp), MSG_DONTWAIT,
00266 reinterpret_cast<struct sockaddr *>(&m_addr),
00267 &len);
00268 if (numRead < 0) {
00269 break;
00270 }
00271 else {
00272
00273
00274 if (sel == 1 && numRead == 0 && bread == 0) {
00275 return -1;
00276 }
00277 }
00278
00279 bread += numRead;
00280 buffer->append(tmp, numRead);
00281 } while (numRead > 0);
00282
00283 return bread;
00284 }
00285
00286
00287
00288 nint32 NTcpSocket::read(NDataStream *buffer, nuint32 bytes) {
00289 nuint32 bread = 0;
00290 fd_set fd;
00291 timeval timeout;
00292 nint32 sel = 0;
00293 socklen_t len = 0;
00294 nint32 numRead = -1;
00295 char tmp[1];
00296
00297 FD_ZERO(&fd);
00298 FD_SET(m_sock, &fd);
00299
00300 timeout.tv_sec = m_timeout;
00301 timeout.tv_usec = 0;
00302
00303 sel = select(m_sock + 1, &fd, NULL, NULL, &timeout);
00304 if (sel < 0) {
00305 throw NNetworkException(nerror(errno), m_host.toString(),
00306 NException::NETWORK, NNetworkException::SOCK_ERROR);
00307 }
00308
00309 if (sel == 0) {
00310
00311 return 0;
00312 }
00313
00314 *buffer = "";
00315 do {
00316 memset(tmp, 0, sizeof(tmp));
00317
00318 numRead = recvfrom(m_sock, &tmp, 1, MSG_DONTWAIT,
00319 reinterpret_cast<struct sockaddr *>(&m_addr),
00320 &len);
00321 if (numRead < 0) {
00322 break;
00323 }
00324 else {
00325
00326
00327 if (sel == 1 && numRead == 0 && bread == 0) {
00328 return -1;
00329 }
00330
00331 }
00332
00333 bread += numRead;
00334 buffer->append(tmp, numRead);
00335 } while (numRead > 0 && bread < bytes);
00336
00337 return bread;
00338 }
00339
00340
00341 nint32 NTcpSocket::readLine(NDataStream *buffer) {
00342 nint32 bread = 0;
00343 fd_set fd;
00344 timeval timeout;
00345 nint32 sel = 0;
00346 socklen_t len = 0;
00347 nint32 numRead = -1;
00348 char tmp[1];
00349
00350 FD_ZERO(&fd);
00351 FD_SET(m_sock, &fd);
00352
00353 timeout.tv_sec = m_timeout;
00354 timeout.tv_usec = 0;
00355
00356 sel = select(m_sock + 1, &fd, NULL, NULL, &timeout);
00357 if (sel < 0) {
00358 throw NNetworkException(nerror(errno), m_host.toString(),
00359 NException::NETWORK, NNetworkException::SOCK_ERROR);
00360 }
00361
00362 if (sel == 0) {
00363
00364 return 0;
00365 }
00366
00367 *buffer = "";
00368 do {
00369 memset(tmp, 0, sizeof(tmp));
00370
00371 numRead = recvfrom(m_sock, &tmp, sizeof(tmp), MSG_DONTWAIT,
00372 reinterpret_cast<struct sockaddr *>(&m_addr),
00373 &len);
00374
00375 if (numRead < 0) {
00376 NDebug::print() << "I did not received an orderly shutdown: "
00377 << nerror(errno);
00378 return -1;
00379 }
00380 else {
00381
00382
00383 if (sel == 1 && numRead == 0 && bread == 0) {
00384 return -1;
00385 }
00386
00387 }
00388 if (tmp[0] == '\n' || tmp[0] == '\0' || numRead < 0) {
00389 break;
00390 }
00391
00392 bread += numRead;
00393 buffer->append(tmp, numRead);
00394 } while (numRead > 0);
00395
00396 return bread;
00397 }
00398
00399 nint32 NTcpSocket::write(const NDataStream &data, nuint32 bytes) {
00400 if (bytes == 0) {
00401 return send(m_sock, data.data(), data.size(), MSG_DONTWAIT);
00402 }
00403
00404 return send(m_sock, data.data(), bytes, MSG_DONTWAIT);
00405 }
00406
00407
00408 nint32 NTcpSocket::writeLine(const NDataStream &data, nuint32 bytes) {
00409 NDataStream tmp = data;
00410
00411 tmp += "\r\n";
00412
00413 if (bytes == 0) {
00414 return send(m_sock, tmp.data(), tmp.size(), MSG_DONTWAIT);
00415 }
00416
00417 return send(m_sock, tmp.data(), bytes, MSG_DONTWAIT);
00418 }