Symbian编程总结-网络与通信-套接字(1)-套接字体系结构与相关API

本文章由杨芹勍原创,如需转载请注明出处。谢谢!

  套接字编程在网络与通信中起着举足轻重的作用。套接字的API最初为方便在BSD Unix中建立TCP/IP的连接而设计的,现在已经成为多种平台(包括Symbian)建立TCP/IP连接的标准API。除了TCP/IP外,套接字API足以通用于其他对应的网络类型和协议。Symbian利用了这个事实,可以使用套接字API在红外线、蓝牙等协议上建立连接。本系列将从网络套接字入手,概述套接字编程的核心实质,同时以大家熟知的.net Socket编程作为参照物,介绍Symbian中的套接字编程。

一、Symbian OS 套接字体系结构

1、客户机/服务器模式

  Symbian OS的套接字是基于客户机/服务器(C/S)模式的。这一点可以从套接字编程中使用到的以下几个类体现:RSocketServ、RSocket、RConnection。RSocketServ派生自RSessionBase,作为与系统服务器通信的父会话;RSocket和RConnection都派生自RSubSessionBase,作为RSocketServ的子会话与系统服务器通信。简单的说,要想进行Socket编程,必须得通过RSocketServ连接系统的套接字服务器。有关Symbian OS的客户机/服务器框架的只是,请参阅“深入篇-客户机/服务器框架系列”文章。

2、客户端的套接字与服务器端的套接字

  这里的“客户端”、“服务器端”与Symbian OS的“客户机/服务器”不是一个概念。这里的“客户端”、“服务器端”指的是在网络中两个互相暴露的两个连接的端点。Socket服务器端被动等待Socket客户端的连接,反过来,Socket客户端主动请求与Socket服务器端连接。一旦连接完毕,两个端点就可以向对方发送或接收数据。

3、面向连接的套接字和面向无连接的套接字

  在此所说的面向连接的套接字为TCP模式,而面向无连接的套接字为UDP模式。有关TCP和UDP的相关知识,请参阅《TCP/IP详解》第二卷的相关章节。

4、异步套接字与同步套接字

  在.net中,Socket类的许多操作都对应有同步版本和异步版本,如:Accept与BeginAccept、EndAccept,Receive与BeginReceive、EndReceive等等。而在Symbian中,RSocket提供的对应方法都为异步函数,我们可以使用活动对象或者User::WaitForRequest方法进行封装调用,请参阅“活动对象正解(4)-异步函数的同步调用 ”。下面例举几个异步方法的原型:

IMPORT_C void Send(const TDesC8& aDesc,TUint someFlags,TRequestStatus& aStatus); IMPORT_C void Recv(TDes8& aDesc,TUint flags,TRequestStatus& aStatus); IMPORT_C void Accept(RSocket& aBlankSocket,TRequestStatus& aStatus);

 

二、Socket编程流程及相关API

  一般情况下,我们会在手机上建立客户端的套接字,去连接远程服务器端的套接字,而且使用的是TCP方式连接。所以,在此我们将以客户端的TCP Socket编程作为入手点,简单介绍Socket编程流程。

首先先用时序图描述一下具体流程:

image

接下来简单的介绍相关API:

  • 连接套接字服务器:RSocketServ::Connect()
    此函数返回错误代码,由于套接字服务器可能已经连接,所以此处可能返回KErrAlreadyExists,应该使用如下方法进行判断:
    TInt err = iSocketServ.Connect(); if (err != KErrNone && err != KErrAlreadyExists) { User::Leave(err); }
  • 打开套接字:RSocket::Open()
    IMPORT_C TInt Open(RSocketServ& aServer,TUint addrFamily,TUint sockType,TUint protocol);

    第一个参数传入套接字服务器,后面几个参数表示连接模式的常量。针对于TCP连接,应该使用如下代码:
    iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp);

    如果记不住每种连接模式对应这三个参数的值,还可以通过使用RSocketServ::FindProtocol的方法,传入模式名称获取一个TProtocolDesc对象,在这个对象中描述了对应的addrFamily、socketType、protocol的值。具体用法请参看SDK。
  • 将网络端点表示为 IP 地址和端口号:TInetAddr
    TInetAddr类似于.net中的IPEndPoint类。使用TInetAddr::Input方法传入IP地址,使用TInetAddr::SetPort方法传入端口号。
  • 连接服务器端Socket:RSocket::Connect
    此方法为异步函数,原型如下:
    IMPORT_C void Connect(TSockAddr& anAddr,TRequestStatus& aStatus);

    其中参数anAddr为我们创建的绑定远程服务器IP地址和端口的TInetAddr类实例。
  • 向服务器端发送数据:RSocket::Send
    此方法为异步函数,原型如下:
    IMPORT_C void Send(const TDesC8& aDesc,TUint someFlags,TRequestStatus& aStatus);
  • 接收服务器端返回的数据:RSocket::Recv
    此方法为异步函数,原型如下:
  • IMPORT_C void Recv(TDes8& aDesc,TUint flags,TRequestStatus& aStatus);

三、小演练:连接服务器端的套接字

1、在此我们使用C#建立一个TCP套接字服务器端,将完成以下几点功能:

  • 监听IP 127.0.0.1和端口8532,等待客户端的连接;
  • 客户端连接后,在屏幕上打印出客户端的IP地址和端口;
  • 等待客户端发送文本数据;
  • 收到数据后将数据内容打印到控制台上;
  • 将收到的数据返回给客户端。

2、使用Symbian C++建立一个TCP套接字客户端,完成以下几点功能:

  • 运用我们以上学到的几个API,连接IP 127.0.0.1和端口8532;
  • 向服务器发送字符串“12345678”;
  • 等待服务器端返回数据;
  • 将服务器端返回的数据(12345678)打印到屏幕上。

点击此处下载服务器端代码(C#)

点击此处下载客户端代码(Symbian C++)

客户端和服务器端运行效果如下:

image

 

四、小结

  这一节作为Socket编程的入门,所涉及的知识点比较少且相对较简单,在下一节里我将详细介绍RSocketServ、RSocket、RConnection的使用方法,并针对TCP、UDP方式进行说明。

 

五、参考文献

  1. Series 60 应用程序开发
posted @ 2008-12-03 02:16  musée  阅读(4419)  评论(12编辑  收藏  举报