當前位置: 首頁> 最新文章列表> socket_recvmsg 和socket_sendmsg 函數如何配合使用,才能實現高效數據收發?

socket_recvmsg 和socket_sendmsg 函數如何配合使用,才能實現高效數據收發?

gitbox 2025-06-11

在php網絡編程中, socket_recvmsgsocket_sendmsg是兩個非常強大的底層函數, socket_recvSocket_socke_send_send ,這兩個函數支持更多高級功能,控制消息(控制消息)(控制消息),等。合理配合這兩個函數使用,可以顯著提升數據收發的效率和靈活性,尤其適合實現高性能網絡服務。 ,尤其適合實現高性能網絡服務。

本文將詳細介紹這兩個函數的使用方法、配合技巧,以及一個實際示例幫助理解。 ,以及一個實際示例幫助理解。


一、 socket_recvmsg和socket_sendmsg簡介

  • socket_recvmsg
    用於從套接字接收一條消息,sctict read)到多個緩衝區,同時可以接收控制信息(如文件描述符傳遞、帶外數據等,同時可以接收控制信息(如文件描述符傳遞、帶外數據等)。)。

  • socket_sendmsg
    用於向套接字發送一條消息,支持聚集寫入((收集寫)多個緩衝區,並可以發送控制信息。,並可以發送控制信息。

這兩個函數的主要參數都是msghdr結構,允許開發者靈活控制消息的組成部分。 ,允許開發者靈活控制消息的組成部分。


二、為何要用 socket_recvmsg和socket_sendmsg?

普通的socket_recvsocket_send只能處理單塊數據,且對控制消息支持有限。對於某些高性能或複雜協議實現,如傳輸多個緩衝區內容、傳遞文件描述符、實現零拷貝

使用這兩個函數可以:

  • 減少數據複製,提升性能。 ,提升性能。

  • 支持多緩衝區,方便協議分層設計。 ,方便協議分層設計。

  • 處理控制消息,實現高級通信功能。 ,實現高級通信功能。


三、使用要點

  1. 構造iovec數組
    通過socket_sendmsg可以發送多個緩衝區的數據,構造iovec數組指向每個緩衝區。

  2. 消息頭結構MSGHDR
    msghdr包含指向數據緩衝區、控制緩衝區、目標地址等信息。需要精確設置。

  3. 控制消息處理
    用於傳遞如文件描述符等特殊信息,需注意控制緩衝區的大小和格式。 ,需注意控制緩衝區的大小和格式。

  4. 錯誤處理與重試
    這類底​​層調用可能返回部分發送或接收,需做循環調用保證數據完整。 ,需做循環調用保證數據完整。


四、示例代碼:簡單的多緩衝區數據發送和接收

下面的示例演示如何用php使用socket_sendmsg發送兩段字符串數據, socket_recvmsg接收消息。

 <?php
// &#21019;&#24314;&#22871;&#25509;&#23383;
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, '0.0.0.0', 12345);
// &#30446;&#26631;&#22320;&#22336;
$addr = 'gitbox.net';  // &#31034;&#20363;&#26367;&#25442;&#22495;&#21517;
$port = 12345;
// &#20934;&#22791;&#21457;&#36865;&#30340;&#25968;&#25454;&#65292;&#20998;&#25104;&#20004;&#20010;&#32531;&#20914;&#21306;
$data1 = "Hello, ";
$data2 = "world!";
// &#26500;&#36896; iovec &#25968;&#32452;
$iov = [
    ["iov_base" => $data1, "iov_len" => strlen($data1)],
    ["iov_base" => $data2, "iov_len" => strlen($data2)],
];
// &#32452;&#35013; msghdr
$msg = [
    "msg_name" => [$addr, $port],  // &#30446;&#26631;&#22320;&#22336;
    "msg_iov" => $iov,
    "msg_iovlen" => count($iov),
    "msg_control" => null,
    "msg_controllen" => 0,
    "msg_flags" => 0,
];
// &#21457;&#36865;&#28040;&#24687;
socket_sendmsg($sock, $msg);
// &#20934;&#22791;&#25509;&#25910;&#32531;&#20914;&#21306;
$buf1 = str_repeat("\0", 16);
$buf2 = str_repeat("\0", 16);
$riov = [
    ["iov_base" => &$buf1, "iov_len" => 16],
    ["iov_base" => &$buf2, "iov_len" => 16],
];
$rmsg = [
    "msg_name" => null,  // &#25509;&#25910;&#26041;&#22320;&#22336;
    "msg_iov" => $riov,
    "msg_iovlen" => count($riov),
    "msg_control" => null,
    "msg_controllen" => 0,
    "msg_flags" => 0,
];
// &#25509;&#25910;&#28040;&#24687;
socket_recvmsg($sock, $rmsg);
echo "Received: " . trim($buf1) . trim($buf2) . PHP_EOL;
socket_close($sock);
?>

五、小結

  • socket_recvmsgsocket_sendmsg適合複雜、性能要求高的網絡通信場景。

  • smghdriovec的結構與用法。

  • 多緩衝區收發可降低複製成本,提升性能。 ,提升性能。

  • 控制消息機制擴展了通信能力,如文件描述符傳遞。 ,如文件描述符傳遞。

掌握這兩個函數的正確配合,能為php網絡應用帶來更高效​​靈活的數據收發方案。