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:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::InitializeL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( iServerSocket.Connect() );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
在初始化只有,这个Socket就算是打开了。一个Socket可以以两种方式打开,空的Socket或是带着特殊协议的Socket。空白的Socket在连接到匹配的client之前不能使用数据传递,使用Accpt()来接收Client的连接。当打开Socket时,它的类型和角色必须要确定,角色当然就是指Server或者Client了。作为Server,两个Socket都需要打开,一个用来监听连接请求,另一个是空白Socket,用来传递数据给Client。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::OpenL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInt result;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( iSocketRole == EClient )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iSocket.Open( iServerSocket, KAfInet,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
KSockStream, KUndefinedProtocol);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iListernerSocket.Open( iServerSocket,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
KAfInet, KSockStream, KUndefinedProtocol );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iSocket.Open( iServerSocket );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
Socket的构造依赖与Socket的类型和角色。一个无连接的Socket很容易构造,本地地址使用Bind()简单地指派,客户端的Socket流类型必须使用Connect()指派远程Socket的地址。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::ConfigureL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( iSocketRole == EClient )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInetAddr serverAddr( INET_ADDR(127,0,0,1), KServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocket.Connect( serverAddr, iStatus );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInetAddr anyAddrOnServerPort( KInetAddrAny, KServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Bind( anyAddrOnServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// Set up a queue for incoming connections
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Listen( KQueueSize );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// Accept incoming connections
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Accept( iSocket, iStatus );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
SetActive();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
不同类型和角色Socket使用不同的函数来收发数据:数据包Socket使用SendTo ()和RecvFrom(),而流Socket使用Send()和Recv()。流Socket还有不同版本的Send()和Recv()重载函数提供使用。所有的函数都带一个Buffer作为参数来发送或者读取。
需要注意的是,在串行通信中,数据经常是传递8-bit bytes,甚至在Unicode系统里也这样。一个可选的参数可以用来设置传递的标志,比如这是紧急的数据;另一个参数是发送读取的长度。在很多情况下,人们使用计时器来防止万一无限制的等待读取或者发送。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::Receive()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( !iSocketRxAO->IsActive() )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocketRxAO->Recv();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CRecSocketAO::Recv()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (!IsActive())
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocket.RecvOneOrMore( iBuffer, 0, iStatus, iRecvLen );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
SetActive();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
使用完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的域名解析需要和附近的设备来收发请求获取。
在 TCP/IP Sockets打开之前,一个与Socket Server的会话必须已经建立。这是Socket连接初始化阶段的唯一要求。消息通道的数量可以传递到方法中,这个数量标示了最多可有有多少个异步的操作允许在任何时候运行。这个默认值是KESockDefaultMessageSLots=8;如果值太小的话,可能会返回KErrServerBusy错误值。一个合理的信道数量值应该是N+2,N是当前的数量。初始化函数创建一个会话到Socket Server:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::InitializeL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( iServerSocket.Connect() );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
在初始化只有,这个Socket就算是打开了。一个Socket可以以两种方式打开,空的Socket或是带着特殊协议的Socket。空白的Socket在连接到匹配的client之前不能使用数据传递,使用Accpt()来接收Client的连接。当打开Socket时,它的类型和角色必须要确定,角色当然就是指Server或者Client了。作为Server,两个Socket都需要打开,一个用来监听连接请求,另一个是空白Socket,用来传递数据给Client。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::OpenL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInt result;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( iSocketRole == EClient )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iSocket.Open( iServerSocket, KAfInet,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
KSockStream, KUndefinedProtocol);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iListernerSocket.Open( iServerSocket,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
KAfInet, KSockStream, KUndefinedProtocol );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
result = iSocket.Open( iServerSocket );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
User::LeaveIfError( result );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
Socket的构造依赖与Socket的类型和角色。一个无连接的Socket很容易构造,本地地址使用Bind()简单地指派,客户端的Socket流类型必须使用Connect()指派远程Socket的地址。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::ConfigureL()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( iSocketRole == EClient )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInetAddr serverAddr( INET_ADDR(127,0,0,1), KServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocket.Connect( serverAddr, iStatus );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
TInetAddr anyAddrOnServerPort( KInetAddrAny, KServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Bind( anyAddrOnServerPort );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// Set up a queue for incoming connections
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Listen( KQueueSize );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// Accept incoming connections
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iListenerSocket.Accept( iSocket, iStatus );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
SetActive();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
不同类型和角色Socket使用不同的函数来收发数据:数据包Socket使用SendTo ()和RecvFrom(),而流Socket使用Send()和Recv()。流Socket还有不同版本的Send()和Recv()重载函数提供使用。所有的函数都带一个Buffer作为参数来发送或者读取。
需要注意的是,在串行通信中,数据经常是传递8-bit bytes,甚至在Unicode系统里也这样。一个可选的参数可以用来设置传递的标志,比如这是紧急的数据;另一个参数是发送读取的长度。在很多情况下,人们使用计时器来防止万一无限制的等待读取或者发送。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CTcpIpSocketServerEngine::Receive()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ( !iSocketRxAO->IsActive() )
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocketRxAO->Recv();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void CRecSocketAO::Recv()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (!IsActive())
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iSocket.RecvOneOrMore( iBuffer, 0, iStatus, iRecvLen );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
SetActive();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
使用完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的域名解析需要和附近的设备来收发请求获取。
相关文章推荐
- 数据连接linux网络编程之TCP/IP基础(四):TCP连接的建立和断开、滑动窗口
- 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP
- 由tcpip.sys损坏引起的网络无法连接的问题
- Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况
- C#网络编程(一)——C#开发TCP/IP聊天室
- 用tcp/ip进行网络连接(第2-5章 笔记)
- Java网络编程(一) TCP/IP,http,socket,长连接,短连接
- 【网络】TCP/IP连接为什么是三次握手?
- libcurl网络连接使用tcp/ip
- iOS 开发 网络编程详解之OSI七层模型和TCP/IP四层模型
- libcurl网络连接使用tcp/ip
- XMPP框架 微信项目开发之网络通信基础——OSI_TCP/IP 参考模型的理解
- Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况
- 如何应用TCP/IP的套接字开发网络通信应用程序
- C++开源TCP/IP网络开发框架:ACE从入门到精通V9.5
- ios开发网络知识 TCP,IP,HTTP,SOCKET区别和联系
- 如何应用TCP/IP的套接字开发网络通信应用程序
- 连接失败 Sqlstate :'01000' Sql server错误:10061 [Microsoft][ODBC Sql Server Driver][TCP/IP Sockets] c
- 【网络】TCP/IP连接三次握手
- libcurl网络连接使用tcp/ip