int IOCPNetwork::send(iocp_key_t key, const byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); /* * 执行WSARecv */ int ret = IOCP_PENDING; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { /* 允许一个接收操作和一个发送操作同时进行 */ ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { assert(context->writeOlp.oppType == IOCP_NONE); context->writeOlp.oppType = IOCP_SEND; context->writeOlp.buf = const_cast<byte*>(buf); context->writeOlp.len = len; context->writeOlp.timeout = timeout; assert(context->writeOlp.timer == NULL); context->writeOlp.iocpProc = func; context->writeOlp.param = param; context->writeOlp.realLen = len; /* * 检查是否超出速度限制,如果是,则延时发送/接收 * 第一次操作不检查 */ size_t delay = 0; if(context->writeOlp.speedLmt > 0 && context->writeOlp.lastCompleteCounter != 0) { /* * 按照最大速度限制,发送 nSended数据完成应该在 nExpectTime 这个时间点完成. */ __int64 expectTime = _hrt.getCounters(static_cast<__int64>(context->writeOlp.transfered * 1.0 / context->writeOlp.speedLmt * 1000)); expectTime += context->startCounter; if(expectTime > context->writeOlp.lastCompleteCounter) /* 完成的时间点提前,说明速度超标 */ { /* 计算出定时器触发的时间. */ delay = static_cast<size_t>(_hrt.getMs(expectTime - context->writeOlp.lastCompleteCounter)); if(delay > IOCP_MAXWAITTIME_ONSPEEDLMT) { /* 超过最长等待时间,下一次发送一个最小包. */ delay = IOCP_MAXWAITTIME_ONSPEEDLMT; if(context->writeOlp.len > IOCP_MINBUFLEN_ONSPEEDLMT) { context->writeOlp.realLen = IOCP_MINBUFLEN_ONSPEEDLMT; } } else { /* 下一次可以发送一个最大包. */ context->writeOlp.realLen = context->writeOlp.len; } //TRACE(_T("delay send:%dms.\r\n"), delay); } } /* * 直接发送或者设置一个定时器延时发送 */ if(delay > 0) { context->writeOlp.oppType = IOCP_DELAY_WRITE; context->writeOlp.timer = _timerQueue.createTimer(delay, delaySendProc, context); } else { /* * 设置超时定时器,然后发送 */ if(context->writeOlp.timeout > 0) { context->writeOlp.timer = _timerQueue.createTimer(context->writeOlp.timeout, readTimeoutProc, context); } ret = realSend(context); if( ret != IOCP_PENDING) { cleanOlp(&context->writeOlp); } } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
void MsgEdit::makeMessage() { if (msg == NULL) return; switch (msg->Type()){ case ICQ_MSGxMSG:{ ICQMsg *m = static_cast<ICQMsg*>(msg); m->Message = edit->text().local8Bit(); if (edit->colorChanged()){ m->BackColor = (edit->background().rgb() & 0xFFFFFF); m->ForeColor = (edit->foreground().rgb() & 0xFFFFFF); pMain->MessageBgColor = m->BackColor(); pMain->MessageFgColor = m->ForeColor(); } break; } case ICQ_MSGxURL:{ ICQUrl *m = static_cast<ICQUrl*>(msg); m->Message = edit->text().local8Bit(); m->URL = urlEdit->text().local8Bit(); break; } case ICQ_MSGxFILE:{ ICQFile *m = static_cast<ICQFile*>(msg); m->Description = edit->text().local8Bit(); m->Name = fileEdit->text().local8Bit(); break; } case ICQ_MSGxCHAT:{ ICQChat *m = static_cast<ICQChat*>(msg); m->Reason = edit->text().local8Bit(); break; } case ICQ_MSGxSMS:{ ICQSMS *m = static_cast<ICQSMS*>(msg); string s; s = edit->text().local8Bit(); s = pClient->clearHTML(s.c_str()); msgTail = trim(QString::fromLocal8Bit(s.c_str())); m->Message = smsChunk(); m->Phone = phoneEdit->lineEdit()->text().local8Bit(); break; } case ICQ_MSGxCONTACTxLIST:{ ICQContacts *m = static_cast<ICQContacts*>(msg); users->fillList(m->Contacts); break; } case ICQ_MSGxAUTHxREQUEST:{ ICQAuthRequest *m = static_cast<ICQAuthRequest*>(msg); m->Message = edit->text().local8Bit(); break; } case ICQ_MSGxAUTHxREFUSED:{ ICQAuthRefused *m = static_cast<ICQAuthRefused*>(msg); m->Message = edit->text().local8Bit(); break; } case ICQ_MSGxAUTHxGRANTED: break; default: log(L_WARN, "Bad message type %u", msg->Type()); return; } if (bMultiply){ msg->Uin.clear(); UserBox *box = static_cast<UserBox*>(topLevelWidget()); if (box->users){ UserView *users = box->users; if (users) users->fillChecked(msg); } } realSend(); }