00001
00008 #include "sysconfig.h"
00009 #include "connection.h"
00010 #include "socket.h"
00011 #include "server.h"
00012 #include "log.h"
00013
00018 Connection::Connection(SOCKET sock, Server* server)
00019 : mServer(server), mDisconnectable(false) {
00020 mSock = new Socket(sock);
00021 }
00022
00026 Connection::~Connection() {
00027 delete mSock;
00028 }
00029
00033 Connection::Connection(const Connection& r_conn)
00034 : mServer(r_conn.mServer), mDisconnectable(r_conn.mDisconnectable),
00035 mInBuffer(r_conn.mInBuffer), mOutBuffer(r_conn.mOutBuffer),
00036 mPendingInput(r_conn.mPendingInput) {
00037 mSock = new Socket(*r_conn.mSock);
00038 }
00039
00043 Connection & Connection::operator=(const Connection& r_conn) {
00044 if (this == &r_conn)
00045 return *this;
00046 mServer = r_conn.mServer;
00047 mInBuffer = r_conn.mInBuffer;
00048 mOutBuffer = r_conn.mOutBuffer;
00049 mPendingInput = r_conn.mPendingInput;
00050 delete mSock;
00051 mSock = new Socket(*r_conn.mSock);
00052 return *this;
00053 }
00054
00059 bool Connection::operator==(const Connection& r_conn) const {
00060 return (GetSocket() == r_conn.GetSocket());
00061 }
00062
00073 void Connection::HandleInput() {
00074
00075 while(true) {
00076 char c;
00077 try {
00078 c = mSock->Read();
00079 }
00080 catch (BlockingException &ex) {
00081
00082
00083 mServer->ServerLog().Write("INFO-Connection(recv): Blocking %d on %d",
00084 ex.mErrCode, GetSocket());
00085 break;
00086 }
00087 catch (ShutdownException &ex) {
00088 mDisconnectable = true;
00089
00090 mServer->ServerLog().Write("WARNING-Connection(recv): Shutdown %d on %d",
00091 ex.mErrCode, GetSocket());
00092 return;
00093 }
00094 catch (IOErrorException &ex) {
00095
00096
00097 mServer->ServerLog().Write("ERROR-Connection(recv): IOError %d on %d",
00098 ex.mErrCode, GetSocket());
00099 mDisconnectable = true;
00100 return;
00101 }
00102
00103 mPendingInput += c;
00104
00105 if (mPendingInput.size() > 4096)
00106 break;
00107 }
00108
00109
00110 while(true) {
00111 int pos = mPendingInput.find("\r\n");
00112 if (pos != (int)mPendingInput.npos) {
00113
00114 mInBuffer.push_back(mPendingInput.substr(0,pos));
00115 mPendingInput.erase(0,pos + 2);
00116 } else {
00117
00118 break;
00119 }
00120 }
00121 }
00122
00135 void Connection::HandleOutput() {
00136
00137 while (!mOutBuffer.empty()) {
00138 try {
00139 mSock->Write(mOutBuffer.front());
00140 mOutBuffer.pop_front();
00141 mSock->Flush();
00142 }
00143 catch (BlockingException &ex) {
00144
00145 mServer->ServerLog().Write("INFO-Connection(send): Blocking %d on %d",
00146 ex.mErrCode, GetSocket());
00147 return;
00148 }
00149 catch (IOErrorException &ex) {
00150
00151 mServer->ServerLog().Write("ERROR-Connection(send): IOError %d on %d",
00152 ex.mErrCode, GetSocket());
00153 mDisconnectable = true;
00154 return;
00155 }
00156 }
00157 }
00158
00162 void Connection::Disconnect() {
00163 mServer->ServerLog().Write(
00164 "INFO-Connection(disconnect): Connection %d disconnected", GetSocket());
00165 mSock->Close();
00166 }
00167
00173 void Connection::SendMsg(const string& r_msg) {
00174 mOutBuffer.push_back(r_msg);
00175 }
00176
00185 string* Connection::ReadMsg() {
00186 if (!mInBuffer.empty()) {
00187 string * msg = new string(mInBuffer.front());
00188 mInBuffer.pop_front();
00189 return msg;
00190 }
00191 return NULL;
00192 }
00193
00202 bool Connection::CanBeDisconnected() {
00203 return mDisconnectable;
00204 }
00205
00211 SOCKET Connection::GetSocket() const {
00212 return mSock->GetSocket();
00213 }
00214
00221 bool Connection::HasOutput() {
00222 return !mOutBuffer.empty();
00223 }
00224