學習Socket套接字

2021-08-19 15:19:33 字數 3256 閱讀 8612

在學習之餘,因為乙個小專案,需要用到網路程式設計tcp/ip的方式來連線到伺服器端的資料庫中。所以便在網上看了一些教材和帖子,學習了一下,但是還是有一些問題在此討論討論。

socket是個什麼東西大家就都知道了,我就不去複製貼上啦。那咱首先介紹什麼呢?咱來介紹一下socket程式設計的標頭檔案

sys/types.h:資料型別定義

sys/socket.h:提供socket函式及資料結構

netinet/in.h:定義資料結構sockaddr_in

arpa/inet.h:提供ip位址轉換函式

netdb.h:提供設定及獲取網域名稱的函式

sys/ioctl.h:提供對i/o控制的函式

sys/poll.h:提供socket等待測試機制的函式

但是有個問題出現了,我在windows的編譯環境下複製了上述標頭檔案卻報錯了:c:\users\14246\desktop\server-sql.c[error] sys/socket.h: no such file or directory。

這是為什麼呢?因為這是在linux下編譯的時候的標頭檔案,也就是說我的伺服器是centos7的作業系統,那麼可以用上述的標頭檔案。但是我現在是在windows下寫的客戶端,所以找不到該標頭檔案的路徑。

那該咋辦呢?把上述標頭檔案換成:#include 或者

#include 。但是本人還沒試驗,所以大家可以試試。

標頭檔案講完了,那講一講socket程式設計常用的一些api函式:

①socket()函式:此函式用於建立乙個socket的描述符,這個描述符說明了此次使用的協議。後面的其他函式會呼叫這個描述符來作為引數;

int socket(int domain, int type, int protocol)

第乙個引數是協議域:常用的協議族有,

af_inet

、af_inet6

、af_local

(或稱af_unix

,unix域socket)、

af_route

等等。協議族決定了socket的位址型別,在通訊中必須採用對應的位址,如af_inet決定了要用ipv4位址(32位的)與埠號(16位的)的組合、af_unix決定了要用乙個絕對路徑名作為位址。

第二個引數是socket型別:常用的socket型別有,

sock_stream

、sock_dgram

、sock_raw

、sock_packet

、sock_seqpacket

等等第三個引數是指定的協議

常用的協議有,

ipproto_tcp

、ipptoto_udp

、ipproto_sctp

、ipproto_tipc

等,它們分別對應tcp傳輸協議、udp傳輸協議、stcp傳輸協議、tipc傳輸協議

注意:並不是上面的type和protocol可以隨意組合的,如sock_stream不可以跟ipproto_udp組合。當protocol為0時,會自動選擇type型別對應的預設協議。

bind()函式把乙個位址族中的特定位址進行資料的收發。

通常伺服器在啟動的時候都會繫結乙個眾所周知的位址(如ip位址+埠號),用於提供服務,客戶就可以通過它來接連伺服器;而客戶端就不用指定,有系統自動分配乙個埠號和自身的ip位址組合。這就是為什麼通常伺服器端在listen之前會呼叫

bind

(),而客戶端就不會呼叫,而是在

connect

()時由系統隨機生成乙個。

int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);

第乙個引數是socket描述符:它是通過socket()函式建立了,唯一標識乙個socket。

bind

()函式就是將給這個描述字繫結乙個名字

第二個引數是指向要繫結給sockfd的協議位址
第三個引數是對應位址的長度

③listen(),connect()函式

若是伺服器,在呼叫前兩個函式之後,便會呼叫listen()函式來監聽bind給socket的那個埠。

若是客戶端,這時便呼叫connect()函式來發出連線請求,伺服器便會收到此請求。引數便不一一解釋了。

④accept()函式:

tcp伺服器端依次呼叫了socket(),bind(),listen()函式後,就會監聽指定的socket位址了。

而客戶端依次呼叫了socket(),connect()之後,就會向指定的tcp伺服器傳送了乙個連線請求。而伺服器接收到此請求後,就會呼叫accept()函式接收請求。這樣就建立了連線

int accept(int sockfd, struct sockaddr* addr,socklen_t *addrlen)

注意:accept的第乙個引數為伺服器的socket描述字,是伺服器開始呼叫socket()函式生成的,稱為

監聽socket描述字

;而accept函式返回的是

已連線的socket描述字

。乙個伺服器通常通常僅僅只建立乙個監聽socket描述字,它在該伺服器的生命週期內一直存在。核心為每個由伺服器程序接受的客戶連線建立了乙個已連線socket描述字,當伺服器完成了對某個客戶的服務,相應的已連線socket描述字就被關閉。

⑤read()/write()當客戶端與伺服器已經建立了連線後,便可以呼叫網路io進行讀寫操作了,即實現了網路中不同程序之間的通訊。

這兩個函式還有一些其他函式可以替代,便不一一說明了。

⑥close()函式 在讀寫操作完成後,就要關閉相應的socket描述字。

#include

int close(int fd)

下面的鏈結是乙個大佬寫的詳細說明:

socket套接字學習

本地的程序間通訊 ipc 有很多種方式,但可以總結為下面4類 在本地可以通過程序pid來唯一標識乙個程序,但是在網路中這是行不通的。其實tcp ip協議族已經幫我們解決了這個問題,網路層的 ip位址 可以唯一標識網路中的主機,而傳輸層的 協議 埠 可以唯一標識主機中的應用程式 程序 這樣利用三元組 ...

socket 套接字學習筆記

socket 方法 receive byte 從繫結的 socket 套接字接收資料,將資料存入接收緩衝區。send byte 將資料傳送到連線的 socket。accept 為新建連線建立新的 socket。注意 如果您使用的是面向連線的協議,則 remoteendpoint 屬性將獲取包含 so...

套接字 Socket 定義

套接字介面可分為三類 公認埠 註冊埠 動態和 或私有埠 套接字,簡單的說就是通訊的兩方的一種約定,用套接字中的相關函式來完成通訊過程 應用層通過傳輸層進行資料通訊時,tcp和udp會遇到同時為多個應用程式程序提供併發服務的問題。多個tcp連線或多個應用程式程序可能需要通過同乙個 tcp協議埠傳輸資料...