您的位置:首页 > 理论基础 > 计算机网络

Symbain开发之网络TCP/IP Sockets连接

2008-04-11 19:37 351 查看
TCP/IP Sockets

在 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的域名解析需要和附近的设备来收发请求获取。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: