2013-04-09 52 views
1

我想將圖像編碼爲base64編碼並將其發送到我正在創建的C++服務器。我使用PHP來做到這一點。使用php使用socket_write發送大型數據包

因此,PHP代碼是客戶端,C++代碼是偵聽服務器。

該問題發生在大圖像上;例如70KB的圖像。它在小圖像上正常工作;如5KB。

發生的錯誤是:警告:socket_write() [function.socket-write]:無法寫入套接字[0]:在數據報套接字上發送的消息大於內部消息緩衝區或其他網絡限制,或用於接收數據報的緩衝區成小於數據報本身。

可以解決這個問題,而不會將圖像分成幾個小包?

我只需要發送數據包爲1MB。

這是我使用的代碼:

$con=file_get_contents("image url"); 
$binary_data=base64_encode($con); 
$host = "192.168.35.54"; 
$port = 1060; 
$message = $binary_data; 
// No Timeout 
set_time_limit(0); 
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP) or die("Could not create socket\n"); 
socket_connect($socket, $host, $port) or die("Could not connect to server\n"); 
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n"); 

回答

0

有一些可能出現的問題,你可以有。我假設你正在使用TCP。我還假設你在一次調用socket_write中寫入整個圖像。我的第一個猜測是問題是接收方。當你在接收端讀取套接字時,並不保證在一次讀取中獲取整個數據塊。通常情況下,讀取TCP套接字時,您會讀取一個循環並以這種方式累積數據,直到獲得所需的所有數據,或者出現錯誤。

你可以看到在這個其他SO後一些示例代碼:

Read from socket: Is it guaranteed to at least get x bytes?

編輯

看到這些額外的細節後,我的第一個建議是切換到TCP。你可以這樣做一次發送,然後在接收端循環讀取,就像上面的示例代碼一樣。否則,你將不得不拆分數據包,並建立自己的錯誤檢測代碼以確保所有數據塊都到達,並且按順序重新組合它們,這基本上只是複製了一堆功能TCP已經提供。

+0

我使用UDP發送和接收數據。 這裏是我使用的php代碼: $ con = file_get_contents(「image url」); $ binary_data = base64_encode($ con); $ host =「ip」; $ port = 1060; $ message = $ binary_data; //無超時 set_time_limit(0); \t \t \t \t $插座= socket_create(AF_INET,SOCK_DGRAM,SOL_UDP)或死亡( 「無法創建套接字\ n」); socket_connect($ socket,$ host,$ port)或死(「無法連接到服務器\ n」); socket_write($ socket,$ message,strlen($ message))或死(「無法將數據發送到服務器\ n」); – 2013-04-09 17:32:01

+1

好的,我剛剛看到了您收到的錯誤消息。基本上答案是否定的。你必須打破數據包。但除非你有一個很好的使用UDP的理由,否則我會切換到TCP。 – 2013-04-09 17:33:25

+0

爲什麼有人投這個答案? – 2013-04-12 05:41:39

0

您需要將套接字發送緩衝區設置爲至少與發送的最大UDP數據報一樣大。

不要問我該如何在PHP中做到這一點,但在套接字API級別,它是setsockopt()SO_SNDBUF選項。