網路基礎篇 socket程式設計之TCP伺服器

2021-07-15 15:47:57 字數 3477 閱讀 7797

1.socket程式設計

這些函式名很好記,h標示host(主機),n標示network(網路),l表示32位長整數,s表示16位短整數。

struct sockaddr

socket位址的資料型別

ipv4位址用用sockaddr_in結構體來表示,ipv6用sockaddr_in6結構體表示。unix domain socket的位址用sockaddr_un結構體表示。

各 種socket位址結構體的開頭都是相同的,前16位表⽰示整個結構體的長度(並不是所有unix的實現 都有長度字段,如linux就沒有),後16位表⽰示位址型別。ipv4、ipv6和unixdomain socket的地 址型別分別定義為常數af_inet、af_inet6 af_unix。這樣,只要取得某種sockaddr結構體的 ⾸首位址,不需要知道具體是哪種型別的sockaddr結構體,就可以根據位址型別字段確定結構體中的 內容。因此,socket api可以接受各種型別的sockaddr結構體指標做引數。

我們研究下基於ipv4的網路程式設計

sockaddr_in結構體內容

tcp伺服器需要的函式如下:

socket函式

_______________返回值:非負描述符 – 成功,-1 - 出錯

引數sockfd

被listen函式作用的套接字,sockfd之前由socket函式返回。在被socket函式返回的套接字fd之時,它是乙個主動連線的套接字,也就是此時系統假設使用者會對這個套接字呼叫connect函式,期待它主動與其它程序連線,然後在伺服器程式設計中,使用者希望這個套接字可以接受外來的連線請求,也就是被動等待使用者來連線。由於系統預設時認為乙個套接字是主動連線的,所以需要通過某種方式來告訴系統,使用者程序通過系統呼叫listen來完成這件事。

引數backlog

這個引數涉及到一些網路的細節。在程序正理乙個乙個連線請求的時候,可能還存在其它的連線請求。因為tcp連線是乙個過程,所以可能存在一種半連線的狀態,有時由於同時嘗試連線的使用者過多,使得伺服器程序無法快速地完成連線請求。如果這個情況出現了,伺服器程序希望核心如何處理呢?核心會在自己的程序空間裡維護乙個佇列以跟蹤這些完成的連線但伺服器程序還沒有接手處理或正在進行的連線,這樣的乙個佇列核心不可能讓其任意大,所以必須有乙個大小的上限。這個backlog告訴核心使用這個數值作為上限。

毫無疑問,伺服器程序不能隨便指定乙個數值,核心有乙個許可的範圍。這個範圍是實現相關的。很難有某種統一,一般這個值會小30以內。

當呼叫listen之後,伺服器程序就可以呼叫accept來接受乙個外來的請求。

bzero

原型:extern void bzero(void *s, int n);  

功能:置位元組字串s的前n個位元組為零且包括『\0』。  

說明:bzero無返回值,並且使用strings.h標頭檔案

繫結埠和ip位址bind

int  bind(int sockfd,const

struct sockaddr* myaddr,socklen_t addrlen)

返回值——成功返回0,失敗返回-1

當socket函式返回乙個描述符時,只是存在於其協議族的空間中,並沒有分配乙個具體的協議位址(這裡指ipv4/ipv6和埠號的組合),bind函式可以將一組固定的位址繫結到sockfd上。

其中:

sockfd是socket函式返回的描述符;

myaddr指定了想要繫結的ip和埠號,均要使用網路位元組序-即大端模式;

addrlen是前面struct sockaddr(與sockaddr_in等價)的長度。

字串轉in_addr函式和in_addr轉字串的函式

accept

標頭檔案:

#include

ssize_t write(int fd,const

void* buf,size_t nbytes);

write函式將buf中的nbytes位元組內容寫入檔案描述符fd.成功時返回寫的位元組數.失敗時返回-1. 並設定errno變數. 在網路程式中,當我們向套接字檔案描述符寫時有兩可能.

1)write的返回值大於0,表示寫了部分或者是全部的資料. 這樣我們用乙個while迴圈來不停的寫入,但是迴圈過程中的buf引數和nbyte引數得由我們來更新。也就是說,網路寫函式是不負責將全部資料寫完之後在返回的。

2)返回的值小於0,此時出現了錯誤.我們要根據錯誤型別來處理.

如果錯誤為eintr表示在寫的時候出現了中斷錯誤.

如果為epipe表示網路連線出現了問題(對方已經關閉了連線).

讀函式read原型

ssize_t read(int fd,void* buf,size_t nbyte)

read函式是負責從fd中讀取內容.當讀成功 時,read返回實際所讀的位元組數,如果返回的值是0 表示已經讀到檔案的結束了,小於0表示出現了錯誤.如果錯誤為eintr說明讀是由中斷引起 的, 如果是econnrest表示網路連線出了問題. 和上面一樣,我們也寫乙個自己的讀函式.

伺服器:

客戶端:

執行結果:

在client發起連線請求時,伺服器開闢執行緒來實現可以支援多客戶端訪問。

網路基礎篇 socket網路程式設計之UDP通訊

udp和tcp的區別 udp是無連線的 不可靠的資料協議報,而tcp是面向連線的,提供可靠的位元組流。然而,有些情況更適合用udp而不是tcp。有些流行的應用程式就是用udp實現的 dns 網域名稱系統 nfs 網路檔案系統 和snmp 簡單網路管理協議 還有就是qq也是使用的udp。udp和tcp...

C 網路程式設計之SOCKET應用篇

c 網路程式設計之socket應用篇 2010年06月22日 思想現代化的重要性 論程式設計的遞迴思想 談二叉樹的順序儲存與鏈式儲存結構。關於圖的概念,鄰接矩陣的理解。關於win7中top sites的立體感官。關於系統的設計精髓的討論 封裝思想,設計模式,stl泛型抽象結構化程式設計,以及哈夫曼樹...

網路程式設計之socket

套接字 socket 是乙個抽象層,應用程式可以通過它傳送或接收資料,可對其進行像對檔案一樣的開啟 讀寫和關閉等操作。套接字允許應用程式將i o插入到網路中,並與網路中的其他應用程式進行通訊。網路套接字是ip位址與埠的組合。套接字起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 unix...