段 哲 韓順鋒 黃 巍 丁忠義
(中國船舶重工集團公司第七二二研究所 武漢 430079)
一般來說,對于 Winsock連接,無論是使用TCP協議還是UDP協議,客戶端程序連接服務端程序時無一例外的要指定IP地址(或機器名)和端口號,那么,在端口已知而服務端程序所在機器地址或名稱未知的情況下,怎樣實現客戶端程序發起并建立連接呢?這就是本文需要解決的問題。
TCP(T ransfer Control Protocol)協議是一種面向連接的,可靠的傳輸層協議,可以將它同電話系統相比。面向連接是指一次正常的TCP傳輸需要通過在TCP客戶端和TCP服務端建立特定的虛電路連接來完成,該過程通常被稱為“三次握手”。在開始數據傳輸之前,用戶必須先建立連接。
如果應用程序要使用TCP協議,那么首先必須決定應用程序是服務器還是客戶端。如果要創建一個服務器端,那么應用程序需要“監聽”指定的端口。當客戶端提出連接請求時,服務器端能夠接受請求并建立連接。在連接建立之后,客戶端與服務器端可以自由地互相通訊。
UDP(User Datagram Protocol)協議是一種無連接協議,與TCP操作不同,兩臺計算機之間的傳輸類似于傳遞郵件:消息從一臺計算機發送到另一臺計算機,不與對方建立連接,而是直接就把數據包發送過去。
另外,單次傳輸的最大數據量取決于具體的網絡。同時,一個UDP應用可同時作為應用的客戶或服務器方。
由于UDP協議并不需要建立一個明確的連接,因此建立UDP應用要比建立TCP應用簡單得多。
TCP協議和UDP協議各有所長、各有所短,適用于不同要求的通信環境。TCP協議和 UDP協議之間的差別如表1所示。
本文提出了一種解決引言部分提出的問題的方案,該方案巧妙地將TCP與UDP結合起來,利用其各自的優點,解決客戶端自動查找并連接服務器端的問題,簡單概括起來就是:客戶端首先使用UDP協議自動查找服務器,然后用TCP協議和服務器建立連接。
當客戶端程序啟動以后,采用UDP協議發送廣播消息,廣播IP地址為255.255.255.255,端口1000,那么網絡內所有機器的端口1000都能接收到該廣播消息。廣播消息的格式如表2所示。

表2 客戶端廣播消息格式(頭+ClientIP)
客戶端發送廣播消息的同時,利用UDP協議監聽1001端口。
在服務器端程序中,則要從廣播消息里獲得客戶端的IP地址,然后將本機IP改為和接收到的IP同一網段的不同IP,接著啟動TCP服務器,再采用UDP協議將自己的IP地址發送到客戶端,讓客戶端與自己建立連接。
服務器端首先采用 UDP協議,監聽端口1000,接受到廣播消息以后,就按表2定義的格式進行解析。如果接收到的包長為 30,就判斷前20Byte是否為“Apply for Connection”,如果匹配成功,則取得包內后續的IP地址。將服務器地址更改為和客戶端同網段的不同的IP。例如接收到的包是“Apply for Connection192.168.0.88” ,那么服務器IP改為“192.168.0.223”。服務器IP更改以后,啟動TCP服務器,將TCP協議端口綁定為1002。然后采用 UDP協議向客戶端發送服務器的IP(格式如表3),UDP協議的連接IP地址為接收到的IP,連接端口為1001。

表3 服務器響應廣播消息格式(頭+ServerIP)
客戶端發送廣播消息以后,在1001端口接收到服務器端傳回的 IP以后,就和服務器端建立TCP連接,端口為1002。
服務器與客戶端主要連接流程圖如圖1所示。

圖1 客戶端自動查找服務器并和服務器建立連接
考慮到編程的效率,本文采用VB 6.0實現了上面的方案。利用WinSock控件可以與遠程計算機建立連接,Winsock包含有UDP協議和TCP協議,可用這兩種協議來建立客戶與服務器應用程序來進行數據交換,而且不必了解TCP/IP協議的細節,只需要弄明白其屬性設置和方法的應用即可。
在窗口中添加三個Winsock控件,第一個命名為sockgetdata,采用 UDP協議,將端口綁定為1000,用于接收廣播消息;第二個命名為sockudpsend,采用 UDP 協議,RemotePort為 1001,向客戶端發送服務器地址;第三個命名為sockTcpS-erver,采用 TCP協議,LocalPort為1002,用于和客戶端建立連接。


可在窗口中添加三個Winsock控件,第一個命名為 sockLink,采用 UDP協議,RemotePort為1000,發送廣播消息;第二個命名為 sockGetRemotIP,采用 UDP協議,將端口綁定為1001,接受服務器地址;第三個命名為sockTcpClient,采用TCP協議,LocalPort為1002,用于和服務器端建立連接。具體程序如下:


本文將TCP與UDP協議聯合起來,提供了一種在端口已知而服務端程序所在機器地址或名稱未知的情況下,怎樣實現客戶端程序發起并建立連接的解決方案。此方法不僅提供了連接的方便實用性,而且保證了數據通信系統的高可靠性。
[1]Anthony Jones and Jim Ohlund.Microsoft Windows網路程式設計[M].2005,6
[2]Microsoft Corporation.Visual Basic 6.0中文版程序員指南[M].北京:北京希望電腦公司,1998
[3]W.RICHARD STEVENS BILL FENNER.UNIX網絡編程[M].楊繼張,譯
[4][美]W.Richard Stevens Stephen A.Rago.UNIX環境高級編程[M].第二版.尤晉元,張亞英,戚正偉,譯
[5][美]K.Wall,M >Watson,M.Whitis,et al.GNU/Linux編程指南[M].王勇,王一川,林花軍,等譯.北京:清華大學出版社,2000,7
[6]高傳善,錢松榮,毛迪林.數據通信與計算機網絡[M].北京:高等教育出版社,2000,7