打斷我在GNU/Linux下用C編程的多線程服務器這種怪異的行爲。發送數據時,最終會被SIGPIPE中斷。我設法忽略send()中的信號,並在每次操作之後處理errno,因爲它。的send()總是由EPIPE
因此,它有兩種單獨的發送方法,一種是一次發送大量數據(或者至少嘗試發送),另一種是發送近似相似的數量並將其切片成小塊。最後,我試着用它來保持它發送數據。
do
{
total_bytes_sent += send(client_sd, output_buf + total_bytes_sent,
output_buf_len - total_bytes_sent, MSG_NOSIGNAL);
}
while ((total_bytes_sent < output_buf_len) && (errno != EPIPE));
這醜陋的代碼做的工作在某些情況下,但並非總是如此。
我很確定這不是硬件或ISP問題,因爲這臺服務器運行在六臺歐洲服務器上,四臺在德國,兩臺在法國。
任何想法?
在此先感謝。
編輯1:是的,我注意到這段代碼是蹩腳的(謝謝傑伊)。我最初的意思是,只要客戶切斷通信,這段代碼就會給我一個EPIPE。
編輯2:我試着用一個單一的send()和它隨機給了我同樣的錯誤。這很奇怪,因爲我無法發送大數據塊。我試圖擴大發送緩衝區,但沒有工作。
EDIT 3:按照要求,這是一個較大的代碼塊。
data_buf_len = cur_stream->iframe_offset[cur_stream->iframe_num - 1] - first_offset;
data_buf = cur_stream->data;
output_buf = compose_reply(send_params, data_buf, data_buf_len, &output_buf_len);
/* Obviously, time measuring is *highly* unaccurate, only for
* design consistency purposes (it should return something).
* */
clock_gettime(CLOCK_REALTIME, &start_time);
total_bytes_sent = send(client_sd, output_buf, output_buf_len, MSG_NOSIGNAL);
clock_gettime(CLOCK_REALTIME, &stop_time);
spent_time = (((int64_t)stop_time.tv_sec * NANOSEC_IN_SEC) +
(int64_t)stop_time.tv_nsec) - (((int64_t)start_time.tv_sec * NANOSEC_IN_SEC) +
(int64_t)start_time.tv_nsec);
free(output_buf);
unload_video(cur_video);
if (total_bytes_sent < 0)
{
log_message(MESSAGE, __func__, IMSG_VIDEOSTOP, cur_video->path);
log_message(MESSAGE, __func__, IMSG_VIDEOSTOP, NULL);
}
/* Hope it will not serve >2147483647 seconds (~68 years) of video... */
return ((int)spent_time);
只有一個帶有大緩衝區的send()調用。還有另一個例子,太大而不能放在這裏,它將每個緩衝區分成更小的塊,併爲每個塊調用send()。
即使客戶端沒有切斷通信,您是否確定它會提供EPIPE? – Jay 2010-04-08 14:40:39
很確定,是的,因爲我試着用EPIPE條件先退出。 – 2010-04-09 09:08:27
你可以發佈更多的代碼嗎? – Jay 2010-04-09 09:22:46