摘要:隨著計算機技術以及網絡通信技術的發展,Socket技術已經成為了網絡編程的基礎,SocketAPI提供了進程之間的通信功能。PowerBuilder作為一門程序開發語言在開發信息管理系統以及各類跨平臺數據庫中有著廣泛的應用。文章簡單介紹了Socket的通信原理以及使用方法,并以聊天程序為例講解了如何在PowerBuilder中利用Winsock控件增強網絡功能,實現Socket通信。
關鍵詞:套接字;會話層;數據報;TCP套接字;UDP套接字
中圖分類號:TP393 文獻標識碼:A文章編號:1009-3044(2010)02-334-03
On the Socket Communication is Implemented in PowerBuilder
LU Lu, WANG Yan-ping
(Zhengzhou Railway Vocational and Technical College, Zhengzhou 450052, China)
Abstract: With the computer technology and network communication technology, Socket technology has become the basis of network programming, SocketAPI provide a process of communication between. PowerBuilder as a program development language in the development of information management systems and a variety of cross-platform database has a wide range of applications. Article a brief introduction of the Socket communication theory and the use of methods, and to chat program as an example to explain how to use Winsock control in PowerBuilder to enhance network capabilities to achieve Socket Communications.
Key words: socket; session layer; datagrams; TCP socket; UDP socket
Socket編程接口由4BSD UNIX首先提出,目的是解決不同網絡間通信問題。Socket接口為進程間通信提供了一種新的手段,它不但能用于同一機器中的進程之間的通信,而且支持網絡通信功能。要想弄清楚Socket的工作原理,必須對網絡通訊技術有所了解。在計算機界,為了保證各種網絡、各種機器、各種操作系統之間能進行互聯,進行數據交換,采取了開放式互聯模型,即OSI模型,它將網絡通訊劃分為7個層次。
1 OSI七層模型概述
OSI模型成為計算機之間,以及網絡間進行通信的主要的結構模型。從上到下,各層名稱及其描述依次為:
1) 第七層:應用層(Application Layer):定義了用于在網絡中進行通信和數據傳輸的接口 —用戶程式;提供標準服務,比如虛擬終端、文件以及任務的傳輸和處理。
2) 第六層:表示層(Presentation Layer):掩蓋不同系統間的數據格式的不同性;指定獨立結構的數據傳輸格式;進行數據的編碼和解碼、加密和解密、壓縮和解壓縮。
3) 第五層:會話層(Session Layer):管理用戶會話和對話;控制用戶間邏輯連接的建立和掛斷;報告上一層發生的錯誤。
4) 第四層:傳輸層(Transport Layer):管理網絡中端到端的信息傳送;通過錯誤糾正和流控制機制提供可靠且有序的數據包傳送;提供面向無連接的數據包的傳送。
5) 第三層:網絡層(Network Layer):定義網絡設備間如何傳輸數據;根據唯一的網絡設備地址路由數據包;提供流和擁塞控制以防止網絡資源的損耗。
6) 第二層:數據鏈路層(Data Link Layer):定義操作通信連接的程序;封裝數據包為數據幀;監測和糾正數據包傳輸錯誤。
7) 第一層:物理層(Physical Layer):定義通過網絡設備發送數據的物理方式;作為網絡媒介和設備間的接口;定義光學、電氣以及機械特性。
通過OSI模型,信息可以從一臺計算機的軟件應用程序傳輸到另一臺的應用程序上。比如,要實現計算機A與計算機B之間通信,實際上,通信過程是計算機A上的應用程序要將信息發送到計算機B的應用程序。中間過程如下:
計算機A中的應用程序需要將信息先發送到其應用層(第七層),然后此層將信息發送到表示層(第六層),表示層將數據轉送到會話層(第五層),如此繼續,直至物理層(第一層)。在物理層,數據被放置在物理網絡媒介中并被發送至計算機B。計算機B的物理層接收來自物理媒介的數據,然后將信息向上發送至數據鏈路層(第二層),數據鏈路層再轉送給網絡層,依次繼續直到信息到達計算機B的應用層。最后,計算機B的應用層再將信息傳送給應用程序接收端,從而完成通信過程。
2 Socket概述
2.1 套接字(Socket)所處位置
套接字大致位于OSI模型的會話層。會話層為兩臺計算機之間的數據流提供管理和控制服務。作為該層的一部分,套接字提供一個隱藏從導線上獲取比特和字節的復雜性的抽象。換句話說,套接字允許我們讓應用程序表明它想發送一些字節即可傳輸數據。套接字隱藏了完成該項工作的具體細節。
2.2 套接字的類型
套接字一般有兩種類型:TCP套接字和UDP套接字。兩者都接收傳輸協議數據包并將其內容向前傳送到表示層。
TCP 把消息分解成數據包(數據報,Datagrams),并在接收端以正確的順序把它們重新裝配起來。TCP 還處理對遺失數據包的重傳請求。有了 TCP,位于上層的層要擔心的事情就少多了。
UDP 不提供裝配和重傳請求這些功能。它只是向前傳送信息包。位于上層的層必須確保消息是完整的并且是以正確的順序裝配的。一般而言,UDP 強加給您的應用程序的性能開銷更小,但只在應用程序不會突然交換大量數據并且不必裝配大量數據報以完成一條消息的時候。否則,TCP 才是最簡單或許也是最高效的選擇。
2.3 Socket的使用方法
下面,我們一一給出重要的Socket系統調用的使用方法。
1) 創建 Socket。調用格式為:sockid = socket (af, type, protocol)其參數意義如下:
af:地址族,指本socket所用地址類型。
type:類型,指創建socket的應用程序所希望的通信服務器類型。
protocol:協議,指該socket請求的協議。
2) 指定本地地址—bind()調用。
bind()將本地socket地址與所創建的socket聯系起來,即將本socket地址賦予socket,以指定本地半相關。bind()的作用相當于給socket命名,調用格式為bind(sockid,localaddr,addrlen)
其參數意義如下:
sockid:socket號。
localaddr:本地socket地址。
addrlen:地址長度。
3) 建立socket連接—connect()與 accept()調用。
這兩個系統調用用于完成整個相關的建立。其中connect用于建立連接。調用格為
connect(sockid,destaddr,addrlen),其中destaddr為指向對方socket地址(信宿地址)結構的指針。
accept()用于面向連接的服務器,其調用格式為:
newsock =accept(sockid,clientaddr,paddrlen),其中clientaddr為指向客戶socket地址指針,paddrlen為客戶socket地址長度。
4) listen()調用
此調用用于面向連接服務器,表明它愿意接收連接,listen()在accept()之前調用,格式為
listen (sockid,quelen),其中quelen 為請求隊列長度。
5) 發送數據—write(),writev(),send()與sendto(),sendmsg()
用于socket數據發送的系統調用一共有五個,其中三個,write(),writev()和send()用于面向連接傳輸,其余兩個用于無連接傳輸。面向連接的調用可以不指定信宿地址,而無連接的調用必須指定。假如無連接socket的雙方均調用過connect(),可以認為是建立有連接的socket,也可以面向連接調用發送數據。
6) 接收數據—read(),readv(),recv()與recvfrom(),recvmsg()
接收數據與發送數據系統調用是一一對應的,兩者參數的最大區別是,前者buffer是一個指針,其所指單元初值為欲讀數據長度,調用后的值是實際讀出的值。
2.4 Socket控件
針對Socket API存在的使用復雜、同步阻塞等問題,Microsoft公司對其進行了封裝,開發了WinSock控件。該控件具體使用簡單、可靠性強、支持事件等特性,對于開發人員而言,就是一個典型的對象,有屬性、方法和事件,因此可以極高地提高軟件的開發效率。
Winsock控件對用戶是不可視的,可以很容易地訪問TCP和UDP網絡服務。其可以被Microsoft Access, Visual Basic,Visual C++或Visual FoxPro開發人員使用。要編寫客戶和服務器應用程序,不需要了解TCP或調用底層Winsock API的具體細節。通過設置Winsock控件的屬性和調用該控件的方法,可以很容易地連接到遠程計算機并進行雙向的數據交換。
數據傳輸協議允許創建和維護與遠程計算機的連接。連接兩臺計算機就可彼此進行數據傳輸。
如果創建客戶應用程序,就必須知道服務器計算機名或者IP地址(RemoteHost屬性),還要知道進行“偵聽”的端口(RemotePort屬性),然后調用Connect方法。
如果創建服務器應用程序,就應設置一個收聽端口(LocalPort屬性)并調用Listen方法。當客戶計算機需要連接時就會發生ConnectionRequest事件。為了完成連接,可調用ConnectionRequest事件內的Accept方法。
建立連接后,任何一方計算機都可以收發數據。為了發送數據,可調用SendData方法。當接收數據時會發生DataArrival事件。調用DataArrival 事件內的GetData方法就可獲取數據。
3 在PB中使用Socket控件的方法
3.1 注冊控件
Winsock控件是微軟件公司提供的處理網絡通信的控件,用它可以進行局域網或則INTERNET的編程開發。該控件并不是默認隨Windows 操作系統自帶的。有兩種方法可以獲得它,一是通過安裝Visual Studio開發環境; 另外一個方法是下載MsWinsck.ocx文件,然后使用“regsvr32 mswinsck.ocx”命令行進行注冊。下面以聊天程序為例演示具體用法。
3.1.1 創建服務器端程序
打開PowerBuilder,然后創建WorkSpace和application對象;創建主窗口w_server對象,并放置控件,如圖1所示。
接下來為控件的事件寫入以下代碼:
Cb_listen控件的clicked事件:
ole_socket.object.localport = 1500;
ole_socket.object.listen();
lb_msg.additem (\"開始監聽\");
ole_socket控件的ConnectionRequest事件
if this.object.state <> 0 then
this.object.close();
end if
this.object.accept( requestid);
lb_msg.additem (\"己經和客戶端建立連接!\");
ole_socket控件的DataArrival事件
string buf;
this.object.getdata ( ref buf);
lb_msg.additem ( string(now(),\"yyyy-mm-dd hh:mm:ss\")+\" 客戶機端說:\"+buf );
cb_send控件的Clicked事件
string buf ;
buf = sle_text.text;
ole_socket.object.senddata ( buf);
lb_msg.additem ( string(now(),\"yyyy-mm-dd hh:mm:ss\")+\" 服務器端說:\"+ buf);
3.1.2 創建客戶端程序。
創建過程與創建服務器端相似,這里就不再重復。客戶端程序的窗口界面如圖2所示。
接下來為控件的事件寫入以下代碼:
Cb_connect事件的clicked事件
ole_socket.object.remotehost = em_host.text;
ole_socket.object.remoteport = integer ( em_port.text);
ole_socket.object.connect();
lb_msg.additem ( \"己經和服務器端建立連接!\" ) ;
Ole_socket控件的DataArriavl事件
string buf;
ole_socket.object.getdata ( ref buf ) ;
lb_msg.additem ( string(now(),\"yyyy-mm-dd hh:mm:ss\")+\" 服務器端說:\"+ buf);
cb_send控件的clicked事件
string buf;
buf = sle_text.text;
ole_socket.object.sendData ( buf) ;
lb_msg.additem ( string(now(),\"yyyy-mm-dd hh:mm:ss\")+\" 客戶機端說:\"+buf ) ;
4 結論
PB是開發大型MIS及各類數據庫跨平臺應用的首選。從數據庫前端工具來講甚至遠遠超過了Oracle的Develop系列等專門的工具,從通用語言角度來講功能也與VB等不相上下。但是多媒體和網絡功能與其他工具相比較弱,該文針對這種情況,結合實際工作中的經驗,討論了如何在PB中通過使用Winsock控件增強網絡功能,不足之處,敬請指正。
參考文獻:
[1] Donahoo M J.TCP/IP Sockets編程(C語言實現)[M].陳宗斌,譯.北京:清華大學出版社,2009.
[2] Iseminger D.網絡連接服務開發人員參考庫Windows Sockets和QOS[M].北京:機械工業出版社,2001(1).
[3] 蔣東興.Windows Sockets 網絡程序設計大全[M].北京:清華大學出版社,1999.
[4] 蔣東興,林鄂華.Windows Sockets網絡程序設計指南[M].北京:清華大學出版社,1995.
[5] 彭建.基于Sockets的桌面視頻會議系統研究[D].長沙:中南大學,2002.
[6] Hatfield B.PowerBuilder 5 應用程序開發指南[M].史森,譯.4版.北京:清華大學出版社,1997.
[7] 陳桂友.PowerBuilder數據庫開發技術[M].北京:機械工業出版社,2009.
[8] 崔社武.PowerBuilder 9.0基礎應用與系統開發[M].北京:電子工業出版社,2004.