Linux网络编程中的几组类似功能的区别
1.bzero與memset
char buff[1024];
memset(buff,0,sizeof(buff));bzero(buff, sizeof(buff));
struct sockaddr_in addr
memset(&addr, 0, sizeof(addr));
bzero(buff, sizeof(buff));
參考《UNIX網絡編程 卷1:套接字聯網API 第3版》1.2的解釋:bzero不是ANSI C函數,起源于Berkeley網絡編程代碼,但是本書使用它卻不用ANSI C的memset函數,因為bzero(帶2個參數)比memset(帶3個參數)更好記。因為原書第一版使用memset有些地方互換了第二個和第三個參數,因為類型一樣,所以調用正常,不過沒做任何事,因為待初始化的字節數被制定為0.程序之所以工作是因為只有少數套接字函數要求網際套接字地址結構的最后8個字節置0。
2.read和write與recv和send
參考《用TCP/IP進行網際互聯 第3卷》:5.7.9? 如同大多數unix系統,在Linux中,程序員可以用read代替recv,用write代替send。對TCP和UDP套接字來時候,read具有和recv一樣的語義,write具有和send一樣的語義。Read和write和主要優點是程序員對它們已經很熟悉;而send和recv的主要優點是它們在程序中標記明顯。
send、recv前面的三個參數和read、write函數是一樣的。
第四個參數可以是0或者是以下組合:
MSG_DONTROUTE:不查找表
是send函數使用的標志,這個標志告訴IP,目的主機在本地網絡上,沒有必要查找表,這個標志一般用在網絡診斷和路由程序里面。
MSG_OOB:接受或者發生帶外數據
表示可以接收和發送帶外數據。
MSG_PEEK:查看數據,并不從系統緩沖區移走數據
是recv函數使用的標志,表示只是從系統緩沖區中讀取內容,而不清楚系統緩沖區的內容。這樣在下次讀取的時候,依然是一樣的內容,一般在有過個進程讀寫數據的時候使用這個標志。
MSG_WAITALL:等待所有數據
是recv函數的使用標志,表示等到所有的信息到達時才返回,使用這個標志的時候,recv返回一直阻塞,直到指定的條件滿足時,或者是發生了錯誤。
即read、write相當于send、recv的最后一個參數用0代替。
1、read 與 recv 區別
read 原則:
??????? 數據在不超過指定的長度的時候有多少讀多少,沒有數據則會一直等待。所以一般情況下:我們讀取數據都需要采用循環讀的方式讀取數據,因為一次read 完畢不能保證讀到我們需要長度的數據,read 完一次需要判斷讀到的數據長度再決定是否還需要再次讀取。
recv 原則:
??????? recv 中有一個MSG_WAITALL 的參數:
??????????????? recv(sockfd, buff, buff_size, MSG_WAITALL),
??????? 正常情況下recv 是會等待直到讀取到buff_size 長度的數據,但是這里的WAITALL 也只是盡量讀全,在有中斷的情況下recv 還是可能會被打斷,造成沒有讀完指定的buff_size的長度。所以即使是采用recv + WAITALL 參數還是要考慮是否需要循環讀取的問題,在實驗中對于多數情況下recv (使用了MSG_WAITALL)還是可以讀完buff_size,
??????? 所以相應的性能會比直接read 進行循環讀要好一些。
?2、read 與 recv函數調用
??????? read(sockfd, buff, buff_size)
??????? write(sockfd, buff, buff_size)
??????? recv(sockfd, buff, buff_size,MSG_WAITALL);?//阻塞模式接收
??????? send(scokfd, buff, buff_size,MSG_WAITALL);?//阻塞模式發送
??????? recv(sockfd, buff, buff_size,MSG_DONTWAIT);?//非阻塞模式接收
??????? send(scokfd, buff, buff_size,MSG_DONTWAIT);?//非阻塞模式發送
??????? recv(sockfd, buff, buff_size,0);
??????? send(scokfd, buff, buff_size,0);
?3、socket編程經驗
??????? 1)盡量使用recv(,,MSG_WAITALL),read必須配合while使用,否則數據量大(240*384)時數據讀不完
??????? 2)編程時寫入的數據必須盡快讀出,否則后面的數據將無法繼續寫入
??????? 3)最佳搭配如下:
??????????????? nbytes = recv(sockfd, buff, buff_size,MSG_WAITALL);
??????????????? nbytes = send(scokfd, buff, buff_size,MSG_WAITALL);
3.close與shutdown
int shutdown(int sockfd,int howto)
TCP連接是雙向的(是可讀寫的),當我們使用close時,會把讀寫通道都關閉,有時侯我們希望只關閉一個方向,這個時候我們可以使用shutdown.針對不同的howto,系統回采取不同的關閉方式.
howto=0這個時候系統會關閉讀通道.但是可以繼續往接字描述符寫.
howto=1關閉寫通道,和上面相反,著時候就只可以讀了.
howto=2關閉讀寫通道,和close一樣 在多進程程序里面,如果有幾個子進程共享一個套接字時,如果我們使用shutdown, 那么所有的子進程都不能夠操作了,這個時候我們只能夠使用close來關閉子進程的套接字描述符.
4.exit與return
exit()
是一個函數,結束一個進程,它將刪除進程使用的內存空間,同時把錯誤信息返回父進程,在父進程中wait系統調用將接受到此返回信息。
return返回函數值,是關鍵字
參考:http://blog.163.com/like12@126/blog/static/63023403201291983117551/http://no001.blog.51cto.com/1142339/493619
總結
以上是生活随笔為你收集整理的Linux网络编程中的几组类似功能的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FAST-CGI安装与使用
- 下一篇: 使用man在线手册页