00001
00009 #include "sysconfig.h"
00010 #include "connection.h"
00011
00012
00017
00018 Connection::Connection(SOCKET sock)
00019 : mSock(sock), mpPendingInput(NULL), mpPendingOutput(NULL),
00020 mDisconnectable(false) {}
00021
00025
00026 Connection::~Connection() {
00027 delete[] mpPendingOutput;
00028 delete[] mpPendingInput;
00029 }
00030
00034
00035 Connection::Connection(const Connection& r_conn)
00036 : mDisconnectable(r_conn.mDisconnectable), mSock(r_conn.mSock),
00037 mpPendingInput(NULL), mpPendingOutput(NULL) {
00038 mInBuffer = r_conn.mInBuffer;
00039 mOutBuffer = r_conn.mOutBuffer;
00040 if (r_conn.mpPendingInput) {
00041 mpPendingInput = new char[strlen(r_conn.mpPendingInput) + 1];
00042 strcpy(mpPendingInput, r_conn.mpPendingInput);
00043 }
00044 if (r_conn.mpPendingOutput) {
00045 mpPendingOutput = new char[strlen(r_conn.mpPendingOutput) + 1];
00046 strcpy(mpPendingOutput, r_conn.mpPendingOutput);
00047 }
00048 }
00049
00053
00054 Connection & Connection::operator=(const Connection& r_conn) {
00055 if (this == &r_conn)
00056 return * this;
00057 mInBuffer = r_conn.mInBuffer;
00058 mOutBuffer = r_conn.mOutBuffer;
00059 if (r_conn.mpPendingInput) {
00060 mpPendingInput = new char[strlen(r_conn.mpPendingInput) + 1];
00061 strcpy(mpPendingInput, r_conn.mpPendingInput);
00062 }
00063 if (r_conn.mpPendingOutput) {
00064 mpPendingOutput = new char[strlen(r_conn.mpPendingOutput) + 1];
00065 strcpy(mpPendingOutput, r_conn.mpPendingOutput);
00066 }
00067 return *this;
00068 }
00069
00086
00087 void Connection::HandleInput() {
00088 string strin;
00089 char inbuf[4096];
00090
00091
00092 if (mpPendingInput) {
00093 strin.append(mpPendingInput);
00094 delete[] mpPendingInput;
00095 mpPendingInput = NULL;
00096 }
00097
00098 while (true) {
00099 int nbytes = recv (mSock, inbuf, 4096, 0);
00100 if (nbytes == 0) {
00101
00102 mDisconnectable = true;
00103 return ;
00104 } else if (nbytes == SOCKET_ERROR) {
00105 int err = WSAGetLastError ();
00106 if (err == WSAEWOULDBLOCK) {
00107
00108
00109 break;
00110 } else {
00111
00112
00113 cout << "Error-Connection(recv):" << err << " on " << mSock << endl;
00114 mDisconnectable = true;
00115 return ;
00116 }
00117 }
00118
00119 inbuf[nbytes] = '\0';
00120 strin.append(inbuf);
00121 }
00122
00123 while (true) {
00124 int pos = strin.find("\r\n");
00125 if (pos != (int)strin.npos) {
00126
00127 mInBuffer.push_back(strin.substr(0, pos));
00128 strin.erase(0, pos + 2);
00129 } else {
00130
00131 if (!strin.empty()) {
00132
00133 mpPendingInput = new char[strin.size() + 1];
00134 strcpy(mpPendingInput, strin.c_str());
00135 }
00136 break;
00137 }
00138 }
00139 }
00140
00153
00154 void Connection::HandleOutput() {
00155 string strout;
00156
00157
00158 if (mpPendingOutput) {
00159 strout.append(mpPendingOutput);
00160 delete[] mpPendingOutput;
00161 mpPendingOutput = NULL;
00162 }
00163
00164 if (!mOutBuffer.empty()) {
00165 strout.append(mOutBuffer.front());
00166 mOutBuffer.pop_front();
00167 }
00168
00169 while (!strout.empty()) {
00170 const char * pstr = strout.c_str();
00171 while (pstr) {
00172 int nbytes = send (mSock, pstr, strlen(pstr), 0);
00173 if (nbytes == SOCKET_ERROR) {
00174 int err = WSAGetLastError ();
00175 if (err == WSAEWOULDBLOCK) {
00176
00177
00178 mpPendingOutput = new char[strlen(pstr) + 1];
00179 strcpy(mpPendingOutput, pstr);
00180 return ;
00181 }
00182
00183 cout << "Error-Connection(recv):" << err << " on " << mSock << endl;
00184 mDisconnectable = true;
00185 return ;
00186 } else if (nbytes < (int)strlen(pstr)) {
00187 pstr += nbytes;
00188 } else {
00189 pstr = NULL;
00190 }
00191 }
00192 strout.erase();
00193
00194 if (!mOutBuffer.empty()) {
00195 strout.append(mOutBuffer.front());
00196 mOutBuffer.pop_front();
00197 }
00198 }
00199 }
00200
00204
00205 void Connection::Disconnect() {
00206 char inbuf[4096];
00207 bool done = false;
00208 shutdown(mSock, SD_SEND);
00209 while (!done) {
00210 int nbytes = recv (mSock, inbuf, 4096, 0);
00211 if (!nbytes || nbytes == SOCKET_ERROR)
00212 done = true;
00213 }
00214 closesocket(mSock);
00215 }
00216
00222
00223 void Connection::SendMsg(const string& r_msg) {
00224 mOutBuffer.push_back(r_msg);
00225 }
00226
00232
00233 string* Connection::ReadMsg() {
00234 if (!mInBuffer.empty()) {
00235 string msg = mInBuffer.front();
00236 mInBuffer.pop_front();
00237 return new string(msg);
00238 }
00239 return NULL;
00240 }
00241
00250
00251 bool Connection::CanBeDisconnected() {
00252 return mDisconnectable;
00253 }
00254
00260
00261 SOCKET Connection::GetSocket() {
00262 return mSock;
00263 }