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 */

Generated on Fri Jul 31 22:33:15 2009 for OpenTTD by  doxygen 1.5.6