4 向 socket 写入数据 Symbian OS socket 客户端API以异步请求的方式实现写入操作.此示例使用一个 active object CSocketsReader来调度这些请求. CSocketWriter 使用一个缓冲(iTransferBuffer)来实时接受来UI的缓冲 (iWriteBuffer),为了避免冲突发送是异步进行的.当写入完成时检测有无其它待写入的缓冲并发送.写入请求如不能在规定时间内完成则取消 1.当用户通过 UI 输入字符,且引擎已连接时,将键入字符转换为byte使用 CSocketsEngine::WriteL 函数发送至引擎 void CSocketsEngine::WriteL(const TDesC8& aData) { // Write data to socket if (iEngineStatus == EConnected) { iSocketsWriter->IssueWriteL(aData); } }
2.请求通过 CSocketWriter::IssueWriteL传递给CSocketWriter class void CSocketsWriter::IssueWriteL(const TDesC8& aData) { if ((iWriteStatus != EWaiting) && (iWriteStatus != ESending)) { User::Leave(KErrNotReady); } if ((aData.Length() + iTransferBuffer.Length()) > iTransferBuffer.MaxLength()) { // 缓冲空间不足 User::Leave(KErrOverflow); } // 加入缓冲数据 iTransferBuffer.Append(aData);
if (!IsActive()) { SendNextPacket(); } }
3.数据复制到transfer缓冲,调用CSocketWriter::SendNextPacket void CSocketsWriter::SendNextPacket() { if (iTransferBuffer.Length() > 0) { // Move data from transfer buffer to actual write buffer iWriteBuffer = iTransferBuffer; iTransferBuffer.Zero(); iSocket.Write(iWriteBuffer, iStatus); // Initiate actual write // Request timeout iTimer->After(iTimeOut); SetActive(); iWriteStatus = ESending; } else { iWriteStatus = EWaiting; } }
4.CSocketsWriter::SendNextPacket移动数据到write buffer,清除transfer buffer并调用 RSocket::Write 函数发送数据请求
5-6.CSocketsWriter 对象状态改为ESending,然后启动计时器控制 RSocket::Write 的状态.调用 SetActive.
7.RSocket::Write 请求完成,调用 CSocketsWriter::RunL 函数 void CSocketsWriter::RunL() { iTimer->Cancel();
// Active object request complete handler if (iStatus == KErrNone) { switch(iWriteStatus) { // Character has been written to socket case ESending: SendNextPacket(); break; default: User::Panic(KPanicSocketsEngineWrite, ESocketsBadStatus); break; }; } else { // Error: pass it up to user interface iEngineNotifier.ReportError(MEngineNotifier::EGeneralWriteError, iStatus.Int()); iWriteStatus = EWaiting; } }
8-9.取消计时器(异步操作完成),调用CSocketsWriter:;SendNextPacket发送所有积累的数据.CSocketsWriter状态改回EWaiting
|