Linux下C語言Socket程式設計

2021-07-26 04:27:23 字數 2720 閱讀 2583

socket用中國話將叫做」套接字」,是用來進行網路資料傳輸的一種約定或者說是一種.

我們通常說的tcp協議和udp協議都是通過socket來進行連線.

每一台連線到網際網路的裝置都會有乙個ip位址,ip位址就像乙個**號碼或者說家庭住址,通過ip才可以唯一地定位到我們要進行網路通訊的網路裝置

乙個裝置一般只有乙個ip位址,但是卻可能同時執行著多個進行網路資料交流的應用程式,如果只有ip位址,計算機雖然可以正確接收到資料報,但是卻不知道要將資料報交給哪個網路程式來處理.

為了區分不同的網路程式,計算機會為每個網路程式分配乙個獨一無二的埠號(port number),例如,web服務的埠號是 80,ftp 服務的埠號是 21,smtp 服務的埠號是 25。

埠(port)是乙個虛擬的、邏輯上的概念。可以將埠理解為一道門,資料通過這道門流入流出,每道門有不同的編號,就是埠號。

計算機之間有很多資料傳輸方式,各有優缺點,常用的有兩種:sock_stream 和 sock_dgram。

1) sock_stream 表示面向連線的資料傳輸方式。資料可以準確無誤地到達另一台計算機,如果損壞或丟失,可以重新傳送,但效率相對較慢。常見的 http 協議就使用 sock_stream 傳輸資料,因為要確保資料的正確性,否則網頁不能正常解析。

2) sock_dgram

表示無連線的資料傳輸方式。計算機只管傳輸資料,不作資料校驗,如果資料在傳輸中損壞,或者沒有到達另一台計算機,是沒有辦法補救的。也就是說,資料錯了就錯了,無法重傳。因為

sock_dgram 所做的校驗工作少,所以效率比 sock_stream 高。

​ 注意:sock_dgram 沒有想象中的糟糕,不會頻繁的丟失資料,資料錯誤只是小概率事件。

有可能多種協議使用同一種資料傳輸方式,所以在 socket 程式設計中,需要同時指明資料傳輸方式和協議。

在linux下,一切皆檔案,socket也不例外,我們可以用操作檔案的i/o函式來操作乙個」socket檔案」,但是,怎麼建立乙個socket檔案吶?這需要用到乙個在 < sys/socket.h >中的函式—-socket().

int socket(int af, int type, int protocol);

af 為位址族(address family),也就是 ip 位址型別,常用的有 af_inet 和 af_inet6。af 是「address family」的簡寫,inet是「inetnet」的簡寫。af_inet 表示 ipv4 位址,例如 127.0.0.1;af_inet6 表示 ipv6 位址,例如 1030::c9b4:ff12:48aa:1a2b。

type 為資料傳輸方式,常用的有 sock_stream 和 sock_dgram,二者區別上面說過.

protocol 表示傳輸協議,常用的有 ipproto_tcp 和 ipptoto_udp,分別表示 tcp 傳輸協議和 udp 傳輸協議。

常用:

tcp套接字:

int tcp_socket = socket(af_inet, sock_stream, ipproto_tcp); //ipproto_tcp表示tcp協議

udp套接字:

int udp_socket = socket(af_inet, sock_dgram, ipproto_udp); //ipproto_udp表示udp協議

雖然用socket()建立了乙個」socket檔案」,但是這個socket檔案還不知道要與哪個ip的哪個埠(port)進行通訊吶~所以我們需要用bind()和connect()來為socket進行配置.

訊息通話的發起段一般使用connect()函式來像另一端傳送請求連線,而等待接受連線的一端使用bind來定義socket要接受哪個埠傳來的連線請求.

connect()

connect()的原型如下:

int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen); //linux

其中:1. int sock 為我們定義的socket檔案

2.struct sockaddr *serv_addr 為sockaddr結構體變數的指標

因為sockaddr結構體的賦值比較麻煩,要把轉化好的ip與埠結合起來寫入,所以一般使用sockaddr_in,然後通過強制型別轉化來帶入connect().

struct sockaddr_in;
3.socklen_t addrlen 為addr變數的大小

一般直接寫sizeof(struct sockaddr)

0.0bind()

bind()的原型如下:

int bind(int sock, struct sockaddr *serv_addr, socklen_t addrlen); //linux

可以看到,bind()的引數與connnect是一模一樣的,其實他們的功能也差不多.都是配置socket屬性,只不過使用bind定義的socke檔案將會用來被動地等待連線,而connect()定義的socket檔案講會主動出擊,去連線其他裝置.

因為差不多,參考上一條吧~~~ /笑cry

不過要注意的一點是,使用connect就立即向目的ip傳送連線請求,而使用bind()函式進行ip與埠繫結後,還要使用listen()函式使socket所指向的埠處於監聽狀態,使用accept()接受請求.

未完待續

Linux下C語言Socket網路程式設計

這裡打算寫乙個在linux系統下執行的socket服務端,然後在win下使用網路助手與其連線,達到資料回顯的功能。廢話不多說了,咱們現在開始。建立socket。將建立socket時返回的套接字描述符與伺服器ip位址和埠進行繫結。開始監聽連線到該伺服器的客戶端。當有客戶端請求與該服務端程式進行連線時,...

linux下C語言socket網路程式設計簡例

這裡給出在linux下的簡單socket網路程式設計的例項,使用tcp協議進行通訊,服務端進行監聽,在收到客戶端的連線後,傳送資料給客戶端 客戶端在接受到資料後列印出來,然後關閉。程式裡有詳細的說明,其中對具體的結構體和函式的實現可以參考其他資料。程式說明 這裡伺服器的埠號和ip位址使用固定的設定,...

linux下C語言socket網路程式設計簡例

這裡給出在linux下的簡單socket網路程式設計的例項,使用tcp協議進行通訊,服務端進行監聽,在收到客戶端的連線後,傳送資料給客戶端 客戶端在接受到資料後列印出來,然後關閉。程式裡有詳細的說明,其中對具體的結構體和函式的實現可以參考其他資料。程式說明 這裡伺服器的埠號和ip位址使用固定的設定,...