在 TCP/IP Sockets打開之前,一個與Socket Server的會話必須已經建立。這是Socket連接初始化階段的唯一要求。消息通道的數量可以傳遞到方法中,這個數量標示了最多可有有多少個非同步的操作允許在任何時候運行。這個預設值是KESockDefaultMessageSLots=8;如果值太小的話,可能會返回KErrServerBusy錯誤值。一個合理的通道數量詞應該是N+2,N是當前的數量。初始化函數創建一個會話到Socket Server:

 

void CTcpIpSocketServerEngine::InitializeL()
{
User::LeaveIfError( iServerSocket.Connect() );
}
在初始化只有,這個Socket就算是打開了。一個Socket可以以兩種方式打開,空的Socket或是帶著特殊協定的Socket。空白的Socket在連接到匹配的client之前不能使用資料傳遞,使用Accpt()來接收Client的連接。當打開Socket時,它的類型和角色必須要確定,角色當然就是指Server或者Client了。作為Server,兩個Socket都需要打開,一個用來監聽連接請求,另一個是空白Socket,用來傳遞資料給Client。

 

void CTcpIpSocketServerEngine::OpenL()
{
TInt result;
if ( iSocketRole == EClient )
{
result = iSocket.Open( iServerSocket, KAfInet,
KSockStream, KUndefinedProtocol);
User::LeaveIfError( result );
}
else
{
result = iListernerSocket.Open( iServerSocket,
KAfInet, KSockStream, KUndefinedProtocol );
User::LeaveIfError( result );
result = iSocket.Open( iServerSocket );
User::LeaveIfError( result );
}
}
Socket的構造依賴與Socket的類型和角色。一個不需連線的Socket很容易構造,本地位址使用Bind()簡單地指派,用戶端的Socket流類型必須使用Connect()指派遠端Socket的位址。

 

void CTcpIpSocketServerEngine::ConfigureL()
{
if ( iSocketRole == EClient )
{
TInetAddr serverAddr( INET_ADDR(127,0,0,1), KServerPort );
iSocket.Connect( serverAddr, iStatus );
}
else
{
TInetAddr anyAddrOnServerPort( KInetAddrAny, KServerPort );
iListenerSocket.Bind( anyAddrOnServerPort );
// Set up a queue for incoming connections
iListenerSocket.Listen( KQueueSize );
// Accept incoming connections
iListenerSocket.Accept( iSocket, iStatus );
}
SetActive();
}
不同類型和角色Socket使用不同的函數來收發資料:資料包Socket使用SendTo ()和RecvFrom(),而流Socket使用Send()和Recv()。流Socket還有不同版本的Send()和Recv()重載函數提供使用。所有的函數都帶一個Buffer作為參數來發送或者讀取。

 

需要注意的是,在串列通信中,資料經常是傳遞8-bit bytes,甚至在Unicode系統裡也這樣。一個可選的參數可以用來設置傳遞的標誌,比如這是緊急的資料;另一個參數是發送讀取的長度。在很多情況下,人們使用計時器來防止萬一無限制的等待讀取或者發送。

 

void CTcpIpSocketServerEngine::Receive()
{
if ( !iSocketRxAO->IsActive() )
{
iSocketRxAO->Recv();
}
}
void CRecSocketAO::Recv()
{
if (!IsActive())
{
iSocket.RecvOneOrMore( iBuffer, 0, iStatus, iRecvLen );
SetActive();
}
}
使用完Socket需要對它進行關閉Close(),在關閉之前,所有未完成的非同步作業都應該取消,使用CancelAll()可以取消所有的操作包括(read,write,input-output control,connect and accept)除非是關閉等不能取消的操作。雖然Close()是同步的方法,但它在socket的input和output都停止的情況下調用非同步的Shutdown()方法來非同步的關閉Socket。

 

因為有大量通信軟體使用了純C的,Symbian OS也有一套BSD4.3Sockets的實現叫做LIBC,這就方便了移植通訊軟體到Symbian上,因為Symbian可以使用C語言實現的通信引擎。LIBC庫包含一個標準TCP/IP庫,包括ARP(address resolution protocol)、RARP(reverse address resolution protocol)、IP(Internet Protocol)、ICMP(Internet control messages protocol)、TCP(transmission control protocol)和UDP(user datagram protocol)

 

另外在資料傳輸過程中,Sockest可能需要使用其他服務,比如Host-name Resolution和Device Discovery。RHostResolver類提供了Host-name Resolution功能變數名稱解決方案。RSocket也是一樣的。Host-name Resolution用在以下四種服務:獲取某個位址的功能變數名稱或者通過功能變數名稱來獲取位址,還可以來設置和獲取本機的主機名稱。

實際上的具體服務和協定是相關的,TCP/IP Sockets需要通過DNS(Domain Name Service)來轉換文本位址和數位IP位址,lrDA的功能變數名稱解析需要和附近的設備來收發請求獲取


創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()