第4章 TCPSocket編程_第1頁
第4章 TCPSocket編程_第2頁
第4章 TCPSocket編程_第3頁
第4章 TCPSocket編程_第4頁
第4章 TCPSocket編程_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、圖4-1 操作系統(tǒng)中關(guān)于以太網(wǎng)卡的信息打開每臺(tái)計(jì)算機(jī)的IP地址都不一樣子網(wǎng)掩碼一般都是255.255.255.0圖4-2 Windows98/me 網(wǎng)絡(luò)屬性圖4-3 Windows98/me IP地址設(shè)置圖4-4 Windows Xp中的TCP/IP屬性對(duì)話框圖4-5網(wǎng)路連通測試成功圖4-6 網(wǎng)路連通測試失敗 在Winsock中套接字可以是阻塞方式,也可以是非阻塞方式。處于阻塞方式的套接字的函數(shù),在完成其任務(wù)之前是不會(huì)返回的。這樣,在該函數(shù)調(diào)用返回前,這個(gè)套接字就不能進(jìn)行其他任何操作,調(diào)用它的進(jìn)程也會(huì)處于掛起狀態(tài),所以稱為阻塞方式。例如,在調(diào)用ReceiveBuf()函數(shù)時(shí),可能要花費(fèi)相當(dāng)長的

2、時(shí)間來等待數(shù)據(jù)的到來,在這段時(shí)間內(nèi),調(diào)用ReceiveBuf ()的進(jìn)程就無法繼續(xù)執(zhí)行。特別是在某些情況下,當(dāng)發(fā)送方的數(shù)據(jù)根本無法到達(dá)時(shí),該進(jìn)程就會(huì)無限地等待下去。除此之外,當(dāng)用戶在長時(shí)間等待后失去耐心而試圖關(guān)閉程序時(shí),還會(huì)導(dǎo)致系統(tǒng)限于危險(xiǎn)境地。BerkeleySocket的很多函數(shù)都是阻塞方式的。 Delphi 6.0中的Winsock有客戶套節(jié)字(ClientSocket、TcpClient)和服務(wù)器套節(jié)字(ServerSocket、TcpServer)之分。ClientSocket和ServerSocket里面均包含一個(gè)Socket對(duì)象,真正用來通信的方法在Socket里面。下面分別討論

3、客戶套節(jié)字的屬性、事件、方法。圖4-7 Delphi 6中網(wǎng)絡(luò)客戶套接字屬性圖4-8 Delphi 6中網(wǎng)絡(luò)客戶套接字事件 function ReceiveLength: Integer; function Socket.ReceiveBuf(var Buf; Count: Integer): Integer; function Socket.SendBuf(var Buf; Count: Integer): Integer; 這兩個(gè)方法可以接收和發(fā)送二進(jìn)制的數(shù)據(jù)也可以發(fā)送字符串?dāng)?shù)據(jù),與Record類型配合可以完成各種數(shù)據(jù)的操作。圖4-10 Delphi 6中網(wǎng)絡(luò)服務(wù)器套接字事件圖4-9 De

4、lphi 6中網(wǎng)絡(luò)服務(wù)器套接字屬性 function ReceiveLength: Integer; function Socket.ReceiveBuf(var Buf; Count: Integer): Integer; function Socket.SendBuf(var Buf; Count: Integer): Integer; 這兩個(gè)方法可以接收和發(fā)送二進(jìn)制的數(shù)據(jù)也可以發(fā)送字符串?dāng)?shù)據(jù),與Record類型配合可以完成各種數(shù)據(jù)的操作。 通信前必須先連接,連接前必須把客戶的Address或Host設(shè)為服務(wù)器計(jì)算機(jī)的IP地址,客戶的Port與服務(wù)器的Port必須相等,服務(wù)器的Active

5、必須設(shè)為true。具體的連接動(dòng)作就是客戶的Active:=true。當(dāng)連接成功后,客戶的OnConnect事件發(fā)生。 應(yīng)當(dāng)注意,一個(gè)服務(wù)器Socket可供若干個(gè)客戶連接。服務(wù)器Socket中專門有一個(gè)記錄數(shù)組Connections記錄客戶的連接情況。 客戶通過SendBuf發(fā)送的信息由服務(wù)器的OnClientRead事件調(diào)用ReceiveBuf接收,服務(wù)器通過SendBuf發(fā)送的信息由客戶的OnRead事件調(diào)用ReceiveBuf接收。 數(shù)據(jù)傳輸協(xié)議允許創(chuàng)建和維護(hù)與遠(yuǎn)程計(jì)算機(jī)的連接。連接兩臺(tái)計(jì)算機(jī)就可彼此進(jìn)行數(shù)據(jù)傳輸。在Visual Basic 6.0中的Winsock沒有客戶與服務(wù)器之分。它

6、既可以當(dāng)客戶用,也可以做服務(wù)器用,完全靠Winsock內(nèi)的屬性、方法、事件的具體配合。 如果創(chuàng)建客戶應(yīng)用程序,就必須知道服務(wù)器計(jì)算機(jī)名或者 IP 地址(RemoteHost 屬性),還要知道進(jìn)行“偵聽”的端口(RemotePort 屬性),然后調(diào)用 Connect 方法。 如果創(chuàng)建服務(wù)器應(yīng)用程序,就應(yīng)設(shè)置一個(gè)收聽端口(LocalPort 屬性)并調(diào)用 Listen 方法。當(dāng)客戶計(jì)算機(jī)需要連接時(shí)就會(huì)發(fā)生 ConnectionRequest 事件。為了完成連接,可調(diào)用 ConnectionRequest 事件內(nèi)的 Accept 方法。圖4-11 Visual Basic 6.0 部件對(duì)話框 對(duì)話前

7、先連接,服務(wù)器必須有自己的IP地址和Port號(hào),并且處于活動(dòng)狀態(tài),等待客戶隨時(shí)的連接請求。 連接時(shí),客戶端先確定服務(wù)器端的IP地址和Port號(hào),然后調(diào)用連接的方法向服務(wù)器請求連接,服務(wù)器同意后將客戶記錄在案,以后就可以互相對(duì)話。 客戶通過發(fā)送方法發(fā)送信息給服務(wù)器,服務(wù)器在接收數(shù)據(jù)的事件里通過接收數(shù)據(jù)的方法接收客戶的信息。服務(wù)器通過發(fā)送方法給客戶回答信息,客戶在接收數(shù)據(jù)的事件里通過接收數(shù)據(jù)的方法接收服務(wù)器的信息。 在整個(gè)對(duì)話過程中,發(fā)送數(shù)據(jù)容易實(shí)現(xiàn),接收數(shù)據(jù)較難實(shí)現(xiàn)。這是因?yàn)榻邮諗?shù)據(jù)是被動(dòng)的,需要隨時(shí)等待,所以這個(gè)過程要放在接收事件里,由接收事件觸發(fā)接收的方法完成接收數(shù)據(jù)的任務(wù)。屬性客戶服務(wù)器a

8、ddress指定服務(wù)器的IP地址要有確定的IPPort與服務(wù)器保持一致要有確定的Port事件客戶服務(wù)器連接覺察服務(wù)器送來的已經(jīng)連通事件覺察客戶送來的請求連接事件收到數(shù)據(jù)覺察服務(wù)器送來的數(shù)據(jù),調(diào)用接收數(shù)據(jù)的方法覺察客戶送來的數(shù)據(jù),調(diào)用接收數(shù)據(jù)的方法表4-7 屬性的基本配合原則表4-8 事件的基本配合原則方法客戶服務(wù)器連接向服務(wù)器請求連接接納接納客戶發(fā)送數(shù)據(jù)根據(jù)實(shí)際需要隨時(shí)可以進(jìn)行處理客戶的請求后返回信息接收數(shù)據(jù)在收到數(shù)據(jù)的事件里進(jìn)行在收到數(shù)據(jù)的事件里進(jìn)行表4-9方法的基本配合原則圖4-12 Delphi 6設(shè)計(jì)的客戶端(1)可與服務(wù)器連接通信。(2)運(yùn)行后等待用戶確定要連接的服務(wù)器的IP地址和p

9、ort號(hào),提示“未連接”,“發(fā)送”按鈕不可用。(3)設(shè)立“斷開”按鈕可斷開與服務(wù)器之間的連接。(4)設(shè)立“打開”按鈕可恢復(fù)與服務(wù)器之間的連接。(5)當(dāng)用戶確定了服務(wù)器的IP地址和port號(hào)后,點(diǎn)擊“連接”按鈕進(jìn)行連接。(6)當(dāng)連接成功后在屏幕上顯示“連接OK”,將“發(fā)送”按鈕設(shè)為可用。(7)當(dāng)服務(wù)器斷開時(shí)顯示“未連接”, “發(fā)送”按鈕設(shè)為不可用。 (8)在發(fā)送文本框里鍵入文本,通過點(diǎn)擊“發(fā)送”按鈕發(fā)送到服務(wù)器。(9)在接收文本框里顯示來自服務(wù)器的文本信息,隨時(shí)等待服務(wù)器送來的信息。 連接的動(dòng)作:ClientSocket1.Active:=true 發(fā)送信息的動(dòng)作:ClientSocket1.S

10、ocket.SendText(信息文本) 接收信息的動(dòng)作:ClientSocket1.Socket.ReceiveText 在事件ClientSocket1Read里進(jìn)行unit ClientUnit;/說明: 這是一個(gè)簡單的實(shí)例, 僅僅表明屬性設(shè)置, 事件編程, 連接及連接情況,/ 發(fā)送數(shù)據(jù),接收數(shù)據(jù)的全過程. 其中的發(fā)送和接收使用的方法/ SendText和ReceiveText 都是針對(duì)字符串的,/ 現(xiàn)實(shí)中的數(shù)據(jù)應(yīng)該是二進(jìn)制數(shù)據(jù), 應(yīng)該使用/ Sendbuf和Receivebuf ,處理過程也要復(fù)雜得多interfaceuses Windows, Messages, SysUtils,

11、Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ScktComp, ExtCtrls;type TForm1 = class(TForm) ClientSocket1: TClientSocket; /客戶 Socket 構(gòu)件 BitBtn1: TBitBtn; /連接按鈕 Label1: TLabel; /顯示連接情況 Memo1: TMemo; /鍵入發(fā)送內(nèi)容的文本編輯器 Button1: TButton; /發(fā)送按鈕 Memo2: TMemo; /存放接收到的內(nèi)容 Label2: TLab

12、el; /顯示收到字符數(shù) Button2: TButton; /斷開按鈕 Button3: TButton; /打開按鈕 LabeledEdit1: TLabeledEdit; /編輯IP地址 LabeledEdit2: TLabeledEdit; /編輯Port號(hào) procedure BitBtn1Click(Sender: TObject); procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Disconnect(Sender: TObject;

13、 Socket: TCustomWinSocket); procedure Button1Click(Sender: TObject); procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); procedure FormShow(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private Private declarations public Publ

14、ic declarations end;var Form1: TForm1;implementation$R *.dfmprocedure TForm1.BitBtn1Click(Sender: TObject); /連接按鈕beginClientSocket1.ClientType:=ctNonBlocking; /選擇無阻塞方式ClientSocket1.Address:=LabeledEdit1.Text; /連接前設(shè)定IP地址ClientSocket1.Port:=strtoint(Labelededit2.Text); /連接前設(shè)定 端口號(hào)ClientSocket1.Active:=

15、true; /連接的動(dòng)作end;procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); /連接成功的事件beginlabel1.Caption:=連接 OK!; /連接成功的提示信息Button1.Enabled:=true; /將發(fā)送按鈕設(shè)為可用end;procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); /連接失敗事件beginlabel1.Caption:=無連接;

16、/連接失敗時(shí)提示信息Button1.Enabled:=false; /將發(fā)送按鈕設(shè)為不能用end;procedure TForm1.Button1Click(Sender: TObject);beginClientSocket1.Socket.SendText(memo1.text); /發(fā)送memo1中的數(shù)據(jù)memo1.Lines.Clear; /清理memo1end;procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); /讀數(shù)據(jù)事件var ss:string;beginss:=Clien

17、tSocket1.Socket.ReceiveText; /及時(shí)獲得服務(wù)器送來的信息memo2.Lines.Add(ss); /將獲得的字符串放進(jìn)memo1,使之成為可見end;procedure TForm1.FormShow(Sender: TObject); /屏幕初始事件begin LabeledEdit2.Text:=inttostr(ClientSocket1.Port); /屏幕上獲得客戶端口號(hào)end;procedure TForm1.Button2Click(Sender: TObject);beginClientSocket1.Close; /關(guān)閉連接end;procedur

18、e TForm1.Button3Click(Sender: TObject);beginClientSocket1.ClientType:=ctNonBlocking; /選擇無阻塞方式ClientSocket1.Address:=LabeledEdit1.Text; /連接前設(shè)定IP地址ClientSocket1.Port:=strtoint(Labelededit2.Text); /連接前設(shè)定 端口號(hào)ClientSocket1.Open; /打開連接 /同 ClientSocket1.Active:=true 意思相同end;end. 創(chuàng)建客戶應(yīng)用程序,必須有Winsock構(gòu)件,還要知道服

19、務(wù)器計(jì)算機(jī)名或者 IP 地址(RemoteHost 屬性),還要知道進(jìn)行“偵聽”的端口(RemotePort 屬性),然后調(diào)用 Connect 方法。由于在實(shí)際中的服務(wù)器IP不確定,所以設(shè)有更改遠(yuǎn)程IP和端口號(hào)的文本框,如圖4-13。 具體編程過程可分為: 連接的動(dòng)作:Winsock1.Connect 發(fā)送信息的動(dòng)作:Winsock1.SendData (文本信息) 接收信息的動(dòng)作:Winsock1.GetData strData在事件Winsock1_DataArrival里進(jìn)行圖4-13 Visual Basic 6設(shè)計(jì)的客戶端用 作 客 戶 的Winsock必須具備可供選擇的服務(wù)器端IP

20、和端口號(hào)Dim mm As Long 接收字符計(jì)數(shù)器Dim kk As Long 接收字節(jié)計(jì)數(shù)器Dim nn As Long 接收次數(shù)計(jì)數(shù)器Private Sub Command1_Click() 連接服務(wù)器按鈕Winsock1.RemoteHost = Text1(0).Text 確定服務(wù)器IP地址Winsock1.RemotePort = Val(Text1(1).Text) 確定服務(wù)器端口號(hào)Winsock1.Connect 連接方法End SubPrivate Sub Command2_Click() 發(fā)送數(shù)據(jù)按鈕Winsock1.SendData (Text3.Text) 發(fā)送方法La

21、bel4.Caption = 字符數(shù) & Len(Text3.Text) 顯示發(fā)送的字符數(shù)Label4.Caption = Label4.Caption + 字節(jié)數(shù) & LenB(Text3.Text) 顯示發(fā)送的字節(jié)數(shù)End SubPrivate Sub Winsock1_Close() 服務(wù)器斷開事件 Winsock1.Close 套接字關(guān)閉 Label3.Caption = 未連接 顯示連接成功 Command2.Enabled = False 允許發(fā)送數(shù)據(jù) End SubPrivate Sub Winsock1_Connect() 連接成功事件 Label3.Capti

22、on = 連接成功 顯示連接成功 Command2.Enabled = True 允許發(fā)送數(shù)據(jù)End SubPrivate Sub Winsock1_DataArrival(ByVal bytesTotal As Long) 收到數(shù)據(jù)事件 Dim strData As String 定義臨時(shí)變量Winsock1.GetData strData, vbString 獲得數(shù)據(jù) mm = mm + Len(strData) 計(jì)算字符數(shù) kk = kk + LenB(strData) 計(jì)算字節(jié)數(shù) Text2.Text = Text2.Text & Chr(13) & Chr(10) & strData 顯示接收內(nèi)容 nn = nn + 1 統(tǒng)計(jì)接收次數(shù) Label2.Caption = 接收到 & nn & 次 & 共 & mm & 字符 Label2.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論