Linux程式設計 8 socket程式設計

2021-10-10 07:27:18 字數 3879 閱讀 2710

在學習linux程式設計時,學會網路程式設計是必不可少的,而linux網路程式設計一般通過socket(套接字)介面實現。在學習socket程式設計之前,我們首先要了解相關網路協議。

linux中繼續使用tcp/ip的網路層結構,即從下到上分為物理層,資料鏈路層,網路層,傳輸層 ,會話層,表示層,應用層。其中,傳輸層在實現通訊服務時發揮了重要作用。傳輸層定義了tcp以及udp協議。tcp是面向連線的通訊協議,提供可靠的資料傳送。tcp將源主機應用層的資料分為多個分段,將每個分段傳輸到網際層,網際層將資料封裝為ip資料報,併發送到目的主機。

網路結構模式分為兩種:客戶機/伺服器模式以及瀏覽器/伺服器模式,在這裡主要圍繞客戶機/伺服器模式展開。乙個完整的tcp程式設計流程如下:伺服器呼叫socket,bind,listen函式完成初始化,接著呼叫accept函式阻塞等待,此時伺服器處於監聽埠的狀態。客戶端呼叫socket函式進行初始化,接著呼叫connect函式發出syn段並阻塞,等待伺服器應答。伺服器應答乙個syn-ack段,客戶端收到後從connect函式返回,同時應答乙個ack段,伺服器收到後從accept函式返回。此時,連線已經成功建立,可以開始傳輸資料了。一般由客戶端發出請求,伺服器處理請求,進行一問一答的方式。所以,伺服器從accept函式返回後,呼叫read函式讀取客戶端的請求,如果沒有請求就阻塞等待。客戶端呼叫write函式傳送請求,伺服器收到請求後從read函式返回,對客戶端的請求進行處理,在此期間伺服器段接著呼叫read函式阻塞等待客戶端的下一條請求。客戶端,伺服器之間傳送,傳輸資料可以用send,recv函式實現。最後,資料傳輸完畢,客戶端呼叫close函式關閉連線,伺服器的read函式就會返回0,伺服器就知道客戶端關閉了連線,也呼叫close函式關閉連線。

套接字是一種通訊機制,用於描述ip位址和埠,是一種特殊的i/o。我們常用流式套接字,即sock_stream,它提供了乙個可靠的,面向連線的資料傳輸服務,資料無差錯無重複地傳送且按傳送順序接受。

int socket(int domain, int type, int protocol) #用於建立乙個新的套接字

#domain又稱為協議族,決定了套接字的位址型別以及在通訊中必須採用對應的位址,常用套接字有af_inet,af_inet6…af_inet決定了要用ipv4位址(32位)與埠號(16位)的組合。

#type指定了套接字型別,常用的套接字型別有sock_stream,sock_dgrom等

#protocol用於指定協議,常用的協議有:ipproto_tcp(tcp協議),ipptoto_udp(udp協議)等,一般置為0,表示使用預設協議。

int bind(int sockfd, const struct sockaddr * addr, socklen_t addrlen) #將乙個套接字繫結到乙個位址上,使得客戶端可以連線

#sockfd:上乙個socket呼叫中獲得的檔案描述符

#addr指向包含繫結位址的結構的指標

#addrlen指的是位址結構的大小

乙個struct sockaddr_in 結構如下:

struct sockaddr_in servaddr; //結構體定義

bzero(&servaddr, sizeof(servaddr)); //結構體清零

servaddr.sin_family = af_inet; //設定位址型別為af_inet

servaddr.sin_addr.s_addr = htonl(inaddr_any);//設定網路位址為inaddr_any

servaddr.sin_port = htons(6666); //設定埠號為6666

int listen(int sockfd, int backlog)

#sockfd:socket呼叫中獲得的檔案描述符

#backlog:sockfd掛起的已連線佇列可以增長的最大長度

int accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen) #建立客戶端程式對該套接字的連線

#sockfd:socket呼叫中獲得的檔案描述符

#addr:指向連線對端的位址,即客戶端位址

#addrlen指定位址結構的大小

int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen) #用於客戶端建立連線,發起三次握手過程。如果連線不能立刻建立起來,connect呼叫會阻塞一段不確定的倒計時時間,這段倒計時時間結束後這次連線就會失敗。

#sockfd:socket呼叫中獲得的檔案描述符

#addr指向伺服器位址

#addrlen指定位址結構的大小

int send(int sockfd, const void * buf, size_t len, int flags) #用於傳送資料

#sockfd:socket呼叫中獲得的檔案描述符

#buf:指向傳送資料的指標

#len:資料的長度

#flags:一般置為0

int recv(int sockfd, const void * buf, size_t len, int flags)

#sockfd:socket呼叫中獲得的檔案描述符

#buf:要讀取資訊的緩衝

#len:緩衝的最大長度

#flags:一般置為0

int close(int fd) #釋放系統分配給套接字的資源,關閉連線

#fd:檔案描述符,在socket程式設計中指sockfd

//伺服器端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define serv_port 6666

#define buf_size 5000

#define file_name_max_size 500

void

fatal

(char

*string)

intmain()

close

(fd)

;close

(sa);}

return0;

}

//客戶端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define serv_port 6666

#define buf_size 5000

#define path " "

//定義檔案位置

#define dest_ip "127.0.0.1"

//ip位址設定為本機

void

fatal

(char

*s)int

main()

c =connect

(listenfd,

(struct sockaddr *

)&cliaddr,

sizeof

(cliaddr));

if(c <0)

fatal

("connect failed");

send

(listenfd, path,

strlen

(path),0

);while(1

)return0;

}

以上程式實現了客戶端與伺服器建立連線,客戶端請求乙個文件並顯示。

Linux核心網路協議棧8 socket監聽

幾個問題 了解以下幾個問題的同學可以直接忽略下文 1 listen 庫函式主要做了什麼?2 什麼是最大併發連線請求數?3 什麼是等待連線佇列?socket 監聽相對還是比較簡單的,先看下應用程式 listen server sockfd,5 其中,第乙個引數 server sockfd為服務端 so...

LINUX程式設計 socket程式設計

什麼是套接字 套接字是一種通訊過程,它使客戶 伺服器系統的開發工作既可以在本地單機上進行,也可以跨網路進行。套接字建立過程 1,建立乙個套接字,這是分配給該伺服器程序的乙個作業系統資源,套接字由伺服器通過系統呼叫socket建立出來的,所以其它程序將不能對它進行訪問。2,給套接字起個名字,用系統呼叫...

SOCKET程式設計(LINUX)

現在的網路程式設計幾乎都是用的socket 本地的程序間通訊 ipc 有很多種方式,但可以總結為下面4類 2.我們要討論的是網路中程序之間如何通訊?在本地可以通過程序pid來唯一標識乙個程序,但是在網路中這是行不通的。三元組 ip位址,協議,埠 就可以標識網路的程序了,網路中的程序通訊就可以利用這個...