socket中read、write、send、recv函數的比較


(ZZ:http://blog.chinaunix.net/uid-26758209-id-3146235.html)

建立好了TCP連接之后,我們就可以把得到的套接字當做文件描述符來使用,由此,想到了網絡程序里面的基本的讀寫函數read和write函數。

Write函數

    Ssize_t write(int fd,const void *buf,size_t nbytes);

    Write函數將buf中的nbytes字節內容寫入到文件描述符中,成功返回寫的字節數,失敗返回-1.並設置errno變量。在網絡程序中,當我們向套接字文件描述舒服寫數據時有兩種可能:

    1、write的返回值大於0,表示寫了部分數據或者是全部的數據,這樣用一個while循環不斷的寫入數據,但是循環過程中的buf參數和nbytes參數是我們自己來更新的,也就是說,網絡編程中寫函數是不負責將全部數據寫完之后再返回的,說不定中途就返回了!

    2、返回值小於0,此時出錯了,需要根據錯誤類型進行相應的處理。

    如果錯誤是EINTR表示在寫的時候出現了中斷錯誤,如果是EPIPE表示網絡連接出現了問題。

Read函數

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

    Read函數是負責從fd中讀取內容,當讀取成功時,read返回實際讀取到的字節數,如果返回值是0,表示已經讀取到文件的結束了,小於0表示是讀取錯誤。

    如果錯誤是EINTR表示在寫的時候出現了中斷錯誤,如果是EPIPE表示網絡連接出現了問題。

 

    有了上面的兩個函數,我們就可以向客戶端或者是服務器端進行數據傳輸了!比如我要傳送一個結構體,可以使用下面的方法:

    客戶端向服務器:

    Struct student stu;

    Write(sock,(void *)&stu,sizeof(struct student));

    服務器讀:

    Char buffer[sizeof(struct student)];

    Struct *my_student;

    Read(sock,(void *)buffer,sizeof(struct student));

    My_student=(struct student)buffer;

    在網絡上傳遞數據時,我們一般把數據轉換為char類型,接收的時候也是一樣的的。沒必要在網絡上傳遞指針。

    Recv函數和send函數

    Recv函數和read函數提供了read和write函數一樣的功能,不同的是他們提供了四個參數。

    Int recv(int fd,void *buf,int len,int flags)

    Int send(int fd,void *buf,int len,int flags)

    前面的三個參數和read、write函數是一樣的。第四個參數可以是0或者是一下組合:

    MSG_DONTROUTE:不查找表

    是send函數使用的標志,這個標志告訴IP,目的主機在本地網絡上,沒有必要查找表,這個標志一般用在網絡診斷和路由程序里面。

    MSG_OOB:接受或者發生帶外數據

    表示可以接收和發送帶外數據。

    MSG_PEEK:查看數據,並不從系統緩沖區移走數據

    是recv函數使用的標志,表示只是從系統緩沖區中讀取內容,而不清楚系統緩沖區的內容。這樣在下次讀取的時候,依然是一樣的內容,一般在有過個進程讀寫數據的時候使用這個標志。

    MSG_WAITALL:等待所有數據

    是recv函數的使用標志,表示等到所有的信息到達時才返回,使用這個標志的時候,recv返回一直阻塞,直到指定的條件滿足時,或者是發生了錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM