tcp_connect.cpp
Go to the documentation of this file.00001
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
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 void TCPConnecter::ThreadEntry(void *param)
00064 {
00065 static_cast<TCPConnecter*>(param)->Connect();
00066 }
00067
00068 void TCPConnecter::CheckCallbacks()
00069 {
00070 for (TCPConnecter **iter = _tcp_connecters.Begin(); iter < _tcp_connecters.End(); ) {
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 void TCPConnecter::KillAll()
00095 {
00096 for (TCPConnecter **iter = _tcp_connecters.Begin(); iter != _tcp_connecters.End(); iter++) (*iter)->killed = true;
00097 }
00098
00099 #endif