Socket 原理與使用

2021-06-03 17:56:25 字數 3859 閱讀 6514

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協議族中的一種。

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

圖1 tcp/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 圖5 int 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()

dword dwip = 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介面使用原理

一 原理 二 套接字的定義 其實套接字這個概念很像linux的遠端登入,他是區分服務端和客戶端的。一台伺服器,可以連線乙個客戶,當然也可以是多個。socket就像是乙個 網路。只有知道區號和 號碼,才能有可能撥通 接 的人可以同時接多個 但是打 的人卻只能打給乙個人。這個時候有乙個問題,多個客戶端連...

socket程式設計原理

if newsock accept mysock.daemonsock,addr,len 1 return 1 accept error.set this socket as a non blocking socket.ioctl newsock,fionbio,flag fd set newsoc...

Socket工作原理

socket可以看成在兩個程式進行通訊連線中的乙個端點,是連線應用程式和網路驅動程式的橋梁,socket在應用程式中建立,通過繫結與網路驅動建立關係。此後,應用程式送給socket的資料,由socket交網路驅動程式向網路上傳送出去。計算機從網路上收到與該socket繫結ip位址和埠號相關的資料後,...