linux下使用fread讀socket套接字的注意點

 2023-10-17 阅读 23 评论 0

摘要:linux下使用fread讀socket套接字的注意點   linux總所周知,一切皆文件。因此我們在讀寫文件時覺得fread,recv這些可以隨便用。下面看看有哪些注意事項呢。   因為C庫的文件處理函數較多,處理起來很靈活。所以在處理套接字時可以用fdopen函數把linux下的文件

linux下使用fread讀socket套接字的注意點

  linux總所周知,一切皆文件。因此我們在讀寫文件時覺得fread,recv這些可以隨便用。下面看看有哪些注意事項呢。

  因為C庫的文件處理函數較多,處理起來很靈活。所以在處理套接字時可以用fdopen函數把linux下的文件描述符轉為一個C庫的FILE文件指針來進行讀寫操作。

fread的返回值

  我們知道在recv出錯時會返回-1,但fread的返回值則不是這樣,它不返回-1。fread/fwrite返回讀到的字節數,返回的字節數小于希望讀的字節數,則表明發生了錯誤或者讀到了文件尾。要使用ferror()和feof來判斷究竟發生了什么。
那么對于一個讀的接口應該按下面這個模板來寫,以處理文件讀寫發生的異常情況

int read_data(FILE *fp, int len)
{int total_len = len;int read_len = 0;int rtn_len = 0;char buffer[RECV_BUF] = {0};while(total_len){read_len = MIN(total_len, RECV_BUF);rtn_len = fread(buffer, sizeof(char), read_len, fp);if(rtn_len < read_len)  /* 讀到數據小于預期 */{if(ferror(fp)){if(errno == EINTR) /* 信號使讀操作中斷 */{/* 不做處理繼續往下走 */;}else if(errno == EAGAIN || errno == EWOULDBLOCK) /* 發生了超時 */{lprintf(MSG_ERROR, "socket recvice timeout: %dms\n", RCV_SND_TIMEOUT);total_len -= rtn_len;lprintf(MSG_DEBUG, "read len: %d\n", rtn_len);break;}else    /* 其他錯誤 */{lprintf(MSG_ERROR, "fread error: %m\n");break;}}else    /* 讀到文件尾 */{lprintf(MSG_ERROR, "socket closed by peer\n");total_len -= rtn_len;lprintf(MSG_DEBUG, "read len: %d\n", rtn_len);break;}}// lprintf(MSG_DEBUG, " %s\n", buffer);total_len -= rtn_len;lprintf(MSG_DEBUG, "read len: %d\n", rtn_len);}if(total_len != 0){lprintf(MSG_ERROR, "we need to read %d bytes, but read %d bytes now\n", len, len - total_len);return -1;}
}

fgets可以和recv混用嗎

  從目前的測試來看不可以!例如我在處理http通信時,我想用fgets來解析http的頭,而后面的數據部分則使用recv來讀,測試發現recv收到的數據前面少了一截。這該如何解釋呢?fgets在讀數據時為提高性能,從socket的接收緩沖區一次性讀了很多數據到自己的緩沖區,然后返回給用戶一行數據,下一次讀數據則優先從C庫自己的緩沖區拿數據。但是下一次你用recv來讀數據了,因此它從socket的接收緩沖區讀到的數據就少了一截。

fread讀數據時超時的表現是什么

  fread本身不支持超時設置,只可以設置阻塞非阻塞。但fread的FILE指針是通過socket轉過來,而socket是可以設置接收發送超時的,所以使用fread接收socket數據時也就具有超時的屬性。但表現和recv超時不太一樣。
  例如設置10s超時,我想recv 1000個字節,10s超時后recv會立馬返回-1.而我想fread 1000個字節,你可能會看見在fread這兒不止卡10s,因為fread會盡量讀滿1000個字節再返回。在C庫實現中,如果10s內,能收到數據,就讀到自己緩沖區,然后接著收數據,直到讀滿1000個字節再返回。如果在10s內讀不到數據那么就返回實際讀到的數據,并把錯誤代碼設置為EAGAIN。
  所以假如設置10s超時,用fread讀8個字節,而對端每9s發送一個字節,那么fread將卡72s然后成功返回。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/143549.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息