Winsock程式設計入門 2

2021-08-23 15:12:57 字數 2746 閱讀 9662

二、簡單的tcp客戶端

介紹

本文是《winsock程式設計入門(1) - 簡單的tcp伺服器》

一文的結局,如果你還沒有讀過第1部分的話,我還是建議你首先讀一下。在本文中,我將示範給你如何編寫乙個簡單的tcp客戶端程式。我們要編寫乙個程式,這個程式將連線到乙個http伺服器,並獲得乙個檔案。

乙個簡單的tcp客戶端程式流程

1、使用wsastartup()初始化winsock庫。

2、使用socket()建立乙個ipproto_tcp socket。

3、使用gethostbyname()/gethostbyaddr()獲取主機資訊。

4、使用connect()和我們建立的套接字連線伺服器。

5、使用send()/recv()傳送和接收資料,直到我們的tcp會話結束。

6、使用closesocket()關閉套接字連線。

7、使用wsacleanup()釋放winsock。

初始化winsock

正如其它每個winsock程式一樣,我們需要初始化winsock庫。這也基本上是一種檢查winsock是否在當前系統可用的方法,對於以前的版本,我們當然希望是這樣。

int wsaret=wsastartup(0x101,&wsadata);

if(wsaret)

return;

建立socket

套接字是一種實體,它擔當了客戶端和伺服器之間的端點。當客戶端連線到伺服器之後,就會存在兩個套接字——客戶端一邊的套接字和相應的伺服器一邊的套接字。讓我們來稱它們為clientsock和serversock。當客戶端在clientsock使用send()時,伺服器可以在serversock使用recv()來接收客戶端所傳送的資料,反之亦然。對於我們的目的,我們使用乙個名為socket()的函式來建立套接字。

socket conn;

conn=socket(af_inet,sock_stream,ipproto_tcp);

if(conn==invalid_socket)

return;

獲取主機資訊

顯然,我們在連線到主機(伺服器)之前,要獲取它的資訊。我們可以使用兩個函式——gethostbyname()和gethostbyaddr()。當我們擁有伺服器的dns名稱時,我們可以使用gethostbyname()函式,例如codeproject.com或ftp.myserver.org之類的名稱。當我們擁有要連線的伺服器的ip位址時,可以使用gethostbyaddr()函式,例如192.168.1.1或202.54.1.100。

顯然,我們希望能使我們的終端使用者既能使用dns名稱,也能使用ip位址。那麼,為了這些工作對他來說透明,我們需要像下面這樣玩乙個小把戲。我們對入口字串使用inet_addr(),這個函式會把乙個ip位址轉換成乙個標準的網路位址格式。這樣一來,如果它返回失敗,我們就可以知道這個字串不是乙個ip位址,如果它成功的話,我們就可以假設它是乙個有效的ip位址了。

if(inet_addr(servername)==inaddr_none)

else

if(hp==null)

連線到伺服器

connect()函式用於向目標伺服器建立連線。我們向它傳遞我們先前建立的套接字和乙個sockaddr結構。我們使用由gethostbyname()/gethostbyaddr()返回的主機位址為sockaddr成員賦值,並輸入乙個要連線的有效埠。

server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);

server.sin_family=af_inet;

server.sin_port=htons(80);

if(connect(conn,(struct sockaddr*)&server,sizeof(server)))

會話

當套接字連線建立後,客戶端和伺服器就可以通過send()和recv()來傳送/接收資料了。這通常稱為tcp會話。對於我們的特定情況,我們需要進行http會話。和那些複雜的smtp或pop3協議相比,它還是比較簡單的。http的get命令用於從http伺服器上獲取檔案。這個檔案可以是html檔案、影象檔案、壓縮檔案、***檔案等等。這樣,這個檔案就會被傳送了(這是它最簡單的形式)。當然,還有一些更複雜的方法來使用這個命令。

在我們的程式中,我們像這樣來傳送get命令:

sprintf(buff,"get %s/r/n/r/n",filepath);

send(conn,buff,strlen(buff),0);

while(y=recv(conn,buff,512,0))

關閉連線

現在我們的會話結束了,我們必須關閉連線。在我們的情況下,http連線在檔案傳送完畢之後就會被伺服器關閉了,但是這不要緊,我們仍然需要關閉我們的套接字並釋放資源。在更加複雜的會話中,我們通常在呼叫closesocket()之前呼叫shutdown()來確定緩衝區已經被重新整理,否則可能會有部分資料丟失。

closesocket(conn);

釋放winsock

我們呼叫wsacleanup()來結束winsock的使用。

wsacleanup();

Winsock程式設計入門 2

二 簡單的tcp客戶端 介紹 本文是 winsock程式設計入門 1 簡單的tcp伺服器 一文的結局,如果你還沒有讀過第1部分的話,我還是建議你首先讀一下。在本文中,我將示範給你如何編寫乙個簡單的tcp客戶端程式。我們要編寫乙個程式,這個程式將連線到乙個http伺服器,並獲得乙個檔案。乙個簡單的tc...

Winsock程式設計入門 1

一 簡單的tcp伺服器 介紹 winsock api是一套供microsoft windows作業系統使用的套接字程式庫,它最初基於berkeley套接字,但是其中加入了一些microsoft的特殊改動。在這篇文章中,我要試著給你介紹如何使用winsock來進行套接字程式設計,並假設你沒有在任何作業...

Winsock程式設計入門 2 定址協議 IPv4

winsock是與協議無關的介面,這裡我們主要介紹廣泛使用的ip協議,其版本為當前的ipv4 ipv6暫不介紹 ipv4定址 ipv4中,計算機的位址用32位的二進位制表示,稱為ip位址.當客戶機使用tcp或udp與伺服器通訊時,必須指定其ip位址及通訊埠.伺服器想要偵聽客戶機請求時,也要指定ip位...