日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

使用read write 读写socket

發布時間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用read write 读写socket 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一旦,我們建立好了tcp連接之后,我們就可以把得到的fd當作文件描述符來使用。

由此網絡程序里最基本的函數就是readwrite函數了。

寫函數:

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

write函數將buf中的nbytes字節內容寫入文件描述符fd.成功時返回寫的字節數.失敗時返回-1.?并設置errno變量.?在網絡程序中,當我們向套接字文件描述符寫時有兩可能.?

1)write的返回值大于0,表示寫了部分或者是全部的數據.?這樣我們用一個while循環來不停的寫入,但是循環過程中的buf參數和nbyte參數得由我們來更新。

也就是說,網絡寫函數是不負責將全部數據寫完之后在返回的。

2)返回的值小于0,此時出現了錯誤.我們要根據錯誤類型來處理.?如果錯誤為EINTR表示在寫的時候出現了中斷錯誤.?如果為EPIPE表示網絡連接出現了問題(對方已經關閉了連接).?

為了處理以上的情況,我們自己編寫一個寫函數來處理這幾種情況.?

int my_write(int fd,void *buffer,int length) 
{ 
int bytes_left; 
int written_bytes; 
char *ptr; 
ptr=buffer; 
bytes_left=length; 
while(bytes_left>0) 
{ /* 開始寫*/ written_bytes=write(fd,ptr,bytes_left); if(written_bytes<=0) /* 出錯了*/ {        if(errno==EINTR) /* 中斷錯誤 我們繼續寫*/ written_bytes=0; else             /* 其他錯誤 沒有辦法,只好撤退了*/ return(-1); } bytes_left-=written_bytes; ptr+=written_bytes;     /* 從剩下的地方繼續寫   */ 
} 
return(0); 
} 

讀函數read?

ssize_t?read(int?fd,void?*buf,size_t?nbyte)?

read函數是負責從fd中讀取內容.當讀成功?時,read返回實際所讀的字節數,如果返回的值是0?表示已經讀到文件的結束了,小于0表示出現了錯誤.如果錯誤為EINTR說明讀是由中斷引起?的,?如果是ECONNREST表示網絡連接出了問題.?和上面一樣,我們也寫一個自己的讀函數.?

int my_read(int fd,void *buffer,int length) 
{ 
int bytes_left; 
int bytes_read; 
char *ptr; 
bytes_left=length; 
while(bytes_left>0) 
{ bytes_read=read(fd,ptr,bytes_read); if(bytes_read<0) { if(errno==EINTR) bytes_read=0; else return(-1); } else if(bytes_read==0) break; bytes_left-=bytes_read; ptr+=bytes_read; 
} 
return(length-bytes_left); 
}

?

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

建立好了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返回一直阻塞,直到指定的條件滿足時,或者是發生了錯誤。

轉載于:https://www.cnblogs.com/jiu0821/p/5833738.html

總結

以上是生活随笔為你收集整理的使用read write 读写socket的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。