# tcp_connect.cpp

Go to the documentation of this file.

    00001 /* $Id: tcp_connect.cpp 15163 2009-01-20 11:28:18Z rubidium $ */
    00002
    00007 #ifdef ENABLE_NETWORK
    00008
    00009 #include "../../stdafx.h"
    00010 #include "../../debug.h"
    00011 #include "../../core/smallvec_type.hpp"
    00012 #include "../../thread.h"
    00013
    00014 #include "tcp.h"
    00015
    00017 static SmallVector<TCPConnecter *,  1> _tcp_connecters;
    00018
    00019 TCPConnecter::TCPConnecter(const NetworkAddress &address) :
    00020   connected(false),
    00021   aborted(false),
    00022   killed(false),
    00023   sock(INVALID_SOCKET),
    00024   address(address)
    00025 {
    00026   *_tcp_connecters.Append() = this;
    00027   if (!ThreadObject::New(TCPConnecter::ThreadEntry, this, &this->thread)) {
    00028     this->Connect();
    00029   }
    00030 }
    00031
    00032 void TCPConnecter::Connect()
    00033 {
    00034   DEBUG(net, 1, "Connecting to %s %d", address.GetHostname(), address.GetPort());
    00035
    00036   this->sock = socket(AF_INET, SOCK_STREAM, 0);
    00037   if (this->sock == INVALID_SOCKET) {
    00038     this->aborted = true;
    00039     return;
    00040   }
    00041
    00042   if (!SetNoDelay(this->sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
    00043
    00044   struct sockaddr_in sin;
    00045   sin.sin_family = AF_INET;
    00046   sin.sin_addr.s_addr = address.GetIP();
    00047   sin.sin_port = htons(address.GetPort());
    00048
    00049   /* We failed to connect for which reason what so ever */
    00050   if (connect(this->sock, (struct sockaddr*) &sin, sizeof(sin)) != 0) {
    00051     closesocket(this->sock);
    00052     this->sock = INVALID_SOCKET;
    00053     this->aborted = true;
    00054     return;
    00055   }
    00056
    00057   if (!SetNonBlocking(this->sock)) DEBUG(net, 0, "Setting non-blocking mode failed");
    00058
    00059   this->connected = true;
    00060 }
    00061
    00062
    00063 /* static */ void TCPConnecter::ThreadEntry(void *param)
    00064 {
    00065   static_cast<TCPConnecter*>(param)->Connect();
    00066 }
    00067
    00068 /* static */ void TCPConnecter::CheckCallbacks()
    00069 {
    00070   for (TCPConnecter **iter = _tcp_connecters.Begin(); iter < _tcp_connecters.End(); /* nothing */) {
    00071     TCPConnecter *cur = *iter;
    00072     if ((cur->connected || cur->aborted) && cur->killed) {
    00073       _tcp_connecters.Erase(iter);
    00074       if (cur->sock != INVALID_SOCKET) closesocket(cur->sock);
    00075       delete cur;
    00076       continue;
    00077     }
    00078     if (cur->connected) {
    00079       _tcp_connecters.Erase(iter);
    00080       cur->OnConnect(cur->sock);
    00081       delete cur;
    00082       continue;
    00083     }
    00084     if (cur->aborted) {
    00085       _tcp_connecters.Erase(iter);
    00086       cur->OnFailure();
    00087       delete cur;
    00088       continue;
    00089     }
    00090     iter++;
    00091   }
    00092 }
    00093
    00094 /* static */ void TCPConnecter::KillAll()
    00095 {
    00096   for (TCPConnecter **iter = _tcp_connecters.Begin(); iter != _tcp_connecters.End(); iter++) (*iter)->killed = true;
    00097 }
    00098
    00099 #endif /* ENABLE_NETWORK */