4 常用網路IO函式

2021-10-08 06:22:30 字數 4147 閱讀 2282

在linux下,一切都是檔案。檔案描述符是核心為了高效管理已經被開啟的檔案所創件的索引。它是乙個非負整數int fd,用於指代被開啟的檔案。所有執行io操作的系統呼叫都是通過檔案描述符來完成的。

open、creat等低階io函式返回檔案描述符。不採用緩衝區去寫,依賴作業系統功能對檔案讀寫,不設檔案結構體指標,只能讀寫二進位制檔案。

區別於fopen等高階io函式。fopen等高階io函式返回的是乙個指向檔案file型別的指標,它們採用緩衝檔案系統。在記憶體為每個檔案開闢乙個快取區,當執行讀操作,從磁碟檔案將資料讀入記憶體緩衝區,裝滿後從記憶體緩衝區依次讀取資料。寫操作同理。記憶體緩衝區的大小影響著實際操作外存的次數,緩衝區越大,操作外存的次數越少,執行速度快,效率高。緩衝區大小由機器而定。

為了執行網路io,會呼叫socket建立套接字。socket會返回套接字描述符。套接字描述符與檔案描述符類似,簡稱sockfd。sockfd也指向乙個套接字(在核心中也是乙個檔案)。呼叫該描述符,可以對套接字進行網路io。

int fd:檔案描述符或套接字描述符。在網路io中,是套接字描述符sockfd。用於指向核心中的某個套接字。

void *buf:乙個空指標,一般傳入乙個指向char陣列的指標,用於快取讀出來的資訊。

size_t nbytes:請求讀位元組數。讀出的資料儲存到buf上,同時檔案讀寫位置後移動count。

讀正確,則返回讀出的位元組數,網路io中,可能由於網路緩衝機制,小於count。

讀失敗,則返回-1;

讀到檔案末尾,則返回0。

該值是函式內的錯誤標誌位。如果讀取失敗,函式呼叫返回-1,且置erron為錯誤。如果讀取失敗,但是不是因為讀取出錯,而是因為遇到中斷,則函式返回-1,但是erron置為 eintr。通過檢查erron,直到讀寫錯在**。

//建立套接字,返回套接字描述符

int client_fd =

socket

(af_inet, sock_stream,0)

;//……

char msg[

1024];

//讀出的資訊儲存在msg上

int rbytes =-1

;if((rbytes =

read

(client_fd, msg,

sizeof

(msg)-1

))>0)

else

printf

("read error=%d(%s)!!!\n"

, errno,

strerror

(errno)

);

#include

ssize_t write

(int fd,

const

void

*buf, size_t nbytes)

int fd:檔案描述符或套接字描述符。在網路io中,是套接字描述符sockfd。用於指向核心中的某個套接字。

const void *buf :乙個const空指標,一般傳入乙個指向char陣列的指標,該陣列儲存我們要寫入的資料。const意味著函式只能讀而不能改變這個指標指向的記憶體單元。

size_t nbytes:請求寫位元組數。把buf上面的nbytes個位元組寫到指定的套接字緩衝區。每次寫之前,會將檔案讀寫位置移動到檔案的當前結尾處,寫完後,再將檔案讀寫位置雜恩公加實際寫的位元組數。

正確,則返回實際寫的位元組數。可能小於nbytes。

失敗,則返回-1;

該值是函式內的錯誤標誌位。如果讀取失敗,函式呼叫返回-1,且置erron為錯誤。如果讀取失敗,但是不是因為讀取出錯,而是因為遇到中斷,則函式返回-1,但是erron置為 eintr。通過檢查erron,直到讀寫錯在**。

//……

//監聽到連線套接字,具體見accept

int client_fd =

accept

(listen_fd,

null

,null);

//……

const

char

*msg=

"hello!"

;//寫入資料if(

write

(client_fd, msg,

strlen

(msg))!=

strlen

(msg)

)printf

("send msg to client error!!!\n");

close

(client_fd)

;

#include

int snprintf (

char

*str, size_t size,

const

char

*format,..

.)

str:目標字串

size:拷貝位元組數(bytes),寫入的最大位元組數

format:格式化字串

…:可變引數

將可變引數(…)按照format格式化成字串,並將字串複製到str中,size為要寫入的字元的最大數目,超過size會被截斷。

如果格式化後的字串長度小於size,則把字串全部複製到str中,並給其後新增乙個』\0』,返回欲寫入的字串長度。

如果大於等於size,超過部分會被截斷。只將其中的size-1複製到str中,並在最後新增』\0』,返回欲寫入的字串長度。

#include

intmain()

string:

123456789

返回值為:9

string:

012345678

返回值為:10

網路io中的read函式和write函式和通常的檔案io有區別。在網路io中使用這兩個函式,可能返回的值小於請求的位元組數。這是因為可能在核心中用於套接字的緩衝區可能已經到達了極限。

此時需要再次呼叫read或write,從而輸入或輸出剩餘位元組。因此考慮使用包裹函式減少這些情況。

#include

ssize_t readn

(int fd,

void

*buf, size_t nbytes)

;

ssize_t readn

(int fd,

void

*buf, size_t nbytes)

//如果等於0,說明讀到了結尾

else

if(nread ==0)

break

;//更新剩餘位元組數

nleft -

= nread;

//更新buf陣列的指標位置,繼續迴圈讀取

ptr +

= nread;

}//返回讀取的位元組數,一般為nbytes。

return

(nbytes - nleft)

;}

#include

ssize_t writen

(int fd,

void

*buf, size_t nbytes)

;

ssize_t  writen

(int fd,

const

void

*buf, size_t nbytes)

nleft -

= nwritten;

ptr +

= nwritten;

}return

(nbytes)

;//返回寫入了多少位元組

}

網路程式設計常用I O函式

read write readv writev 對資料進行整合傳輪及傳送的函式。也就是說,通過writev 函式可以將分散儲存在多個緩衝中的資料一併傳送,通過readv函式可以由多個緩衝分別接收。因此,適當使用這2個函式可以減少i o函式的呼叫次數。下面先介紹writev 函式。include ss...

常用檔案IO函式

include include include int open const char pathname,int flags int open const char pathname,int flags,mode t mode 功能 開啟檔案,如果檔案不存在則可以選擇建立。引數 pathname 檔...

網路程式設計的4種IO模型

select fd zero初始化 fd set將socket加進去 select輪詢 當socket的事件發生時,fd set裡面有相關的socket,如果沒有socket有事件發生,select返回0 fd isset檢測,socket是否還在fd set裡,是的話,表示這個socket有事件發...