揭開Socket程式設計的面紗

2021-06-02 07:20:45 字數 4329 閱讀 6275

對tcp/ip、udp、socket程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問:

1.         什麼是tcp/ip、udp?

2.         socket在**呢?

3.         socket是什麼呢?

4.         你會使用它們嗎?

什麼是tcp/ip、udp?

tcp/ip(transmission control protocol/internet protocol)即傳輸控制協議/網間協議,是乙個工業標準的協議集,它是為廣域網(wans)設計的。

udp(user data protocol,使用者資料報協議)是與tcp相對應的協議。它是屬於tcp/ip協議族中的一種。

這裡有一張圖,表明了這些協議的關係。

圖1tcp/ip協議族包括運輸層、網路層、鏈路層。現在你知道tcp/ip與udp的關係了吧。

socket在**呢?

在圖1中,我們沒有看到socket的影子,那麼它到底在**呢?還是用圖來說話,一目了然。

圖2原來socket在這裡。

socket是什麼呢?

socket是應用層與tcp/ip協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,socket其實就是乙個門面模式,它把複雜的tcp/ip協議族隱藏在socket介面後面,對使用者來說,一組簡單的介面就是全部,讓socket去組織資料,以符合指定的協議。

你會使用它們嗎?

前人已經給我們做了好多的事了,網路間的通訊也就簡單了許多,但畢竟還是有挺多工作要做的。以前聽到socket程式設計,覺得它是比較高深的程式設計知識,但是只要弄清socket程式設計的工作原理,神秘的面紗也就揭開了。

乙個生活中的場景。你要打**給乙個朋友,先撥號,朋友聽到**鈴聲後提起**,這時你和你的朋友就建立起了連線,就可以講話了。等交流結束,結束通話**結束此次交談。   生活中的場景就解釋了這工作原理,也許tcp/ip協議族就是誕生於生活中,這也不一定。

圖3先從伺服器端說起。伺服器端先初始化socket,然後與埠繫結(bind),對埠進行監聽(listen),呼叫accept阻塞,等待客戶端連線。在這時如果有個客戶端初始化乙個socket,然後連線伺服器(connect)

,如果連線成功,這時客戶端與伺服器端的連線就建立了。客戶端傳送資料請求,伺服器端接收請求並處理請求,然後把回應資料傳送給客戶端,客戶端讀取資料,最後關閉連線,一次互動結束。

在這裡我就舉個簡單的例子,我們走的是tcp協議這條路(見圖2)。例子用mfc編寫,執行的介面如下:

圖4

圖5int    receive(socket fd,char *sztext,int len)

if(rc==0)

return len-cnt;

sztext+=rc;

cnt-=rc;

return len;

}int send(socket fd,char *sztext,int len)

監聽執行緒函式:

dword winapi cserverdlg::listenthread(lpvoid lpparam)

{cserverdlg* pdlg = (cserverdlg*)lpparam;

if(pdlg == null)

return 0;

socket  listening = pdlg->m_listening;

//開始監聽是否有客戶端連線。

if(listen(listening,40) == socket_error)

return 0;

char szbuf[max_path];

//初始化

memset(szbuf,0,max_path);

while(1)

socket connectsocket;

sockaddr_in    clientaddr;

int                  nlen = sizeof(sockaddr);

//阻塞直到有客戶端連線,不然多浪費cpu資源。

connectsocket = accept(listening,(sockaddr*)&clientaddr,&nlen);

//都到客戶端的ip位址。

char *paddrname = inet_ntoa(clientaddr.sin_addr);

pdlg->receive(connectsocket,szbuf,100);

//介面上顯示請求資料。

pdlg->setrequesttext(szbuf);

strcat(szbuf," :我是老貓,收到(");

strcat(szbuf,paddrname);

strcat(szbuf,")");

//向客戶端傳送回應資料

pdlg->send(connectsocket,szbuf,100);

return 0;

伺服器端一直在監聽是否有客戶端連線,如有連線,處理客戶端的請求,給出回應,然後繼續監聽。

客戶端:

客戶端的傳送函式:

#define default_port      2000

void cclientdlg::onsend()

dworddwip = 0;      

tchar sztext[max_path];

memset(sztext,0,max_path);

m_ip.getwindowtext(sztext,max_path);

//把字串形式的ip位址轉成in_addr結構需要的形式。

dwip = inet_addr(sztext);

m_requestedit.getwindowtext(sztext,max_path);

sockaddr_in local;

socket sockettmp;

//必須是af_inet,表示該socket在internet域中進行通訊

local.sin_family=af_inet;

//埠號

local.sin_port=htons(default_port);

//伺服器的ip位址。

local.sin_addr.s_un.s_addr=dwip;

初始化socket

sockettmp=socket(af_inet,sock_stream,0);

//連線伺服器

if(connect(sockettmp,(lpsockaddr)&local,sizeof(local)) < 0)

closesocket(sockettmp);

messagebox("連線伺服器失敗。");

return ;

//傳送請求,為簡單只發100位元組,在伺服器端也規定100位元組。

send(sockettmp,sztext,100);

//讀取伺服器端返回的資料。

memset(sztext,0,max_path);

//接收伺服器端的回應。

receive(sockettmp,sztext,100);

tchar szmessage[max_path];

memset(szmessage,0,max_path);

strcat(szmessage,sztext);

//介面上顯示回應資料。

m_replybtn.setwindowtext(szmessage);

closesocket(sockettmp);

客戶端就乙個函式完成了一次通訊。在這裡ip位址為何用127.0.0.1呢?使用這個ip位址,伺服器端和客戶端就能執行在同一臺機器上,這樣除錯方便多了。當然你可以在你朋友的機器上執行server程式(本人在區域網中測試過),在自己的機器上執行client程式,當然輸入的ip位址就該是你朋友機器的ip位址了。

簡單的理論和實踐都說了,現在socket程式設計不神秘了吧?希望對你有些幫助。

揭開Socket程式設計的面紗

對tcp ip udp socket程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3.socket是什麼呢?4.你會使用它們嗎?什麼是tcp ip udp?tcp ip transmission cont...

揭開Socket程式設計的面紗

對 tcp ip udp socket 程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3.socket是什麼呢?4.你會使用它們嗎?什麼是tcp ip udp?tcp ip transmission co...

揭開Socket程式設計的面紗

posted on 2005 12 10 22 59 原始碼工作室 閱讀 42903 編輯收藏 所屬分類 網路程式設計 對tcp ip udp socket程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3...