[英]C: Data forwarding server using epoll ET fills the send buffer
我有以下情況。 我的服務器從遠程服務器(fd_server)接收數據,並將其轉發到客戶端(fd_client)。 我正在使用邊緣觸發的epoll,以便可以處理多個客戶端和多個服務器連接。
程序:
細節:
我的服務器連接到遠程服務器后,將fd_server添加到帶有EPOLLIN標志的epoll控件中。 服務器等待事件。
當epoll_wait返回可讀的fd_server時,我進入下面顯示的循環。
經過一些讀/寫后,我的sctp_sendmsg返回EAGAIN,這意味着sctp發送緩沖區已滿。 如何處理這種情況而又不會丟失已經從fd_server套接字讀取的數據?
是否可以事先知道要發送多少數據,所以我只能讀取正確的數據量?
while(1){
N = recv(fd_server,buf, sizeof buf,0);
if (N == -1){
/* If errno == EAGAIN, that means we have read all
data. So go back to the main loop. */
if (errno != EAGAIN){
perror ("tcp_recv error");
}
break;
}
if(N == 0){
/* End of file. The remote has closed the
connection. */
close(fd_server);
break;
}
pos = 0;
while(pos < N){
got = sctp_sendmsg(fd_client, &buf[pos], N-pos, to, tolen, 0, 0, stream, 0, 0);
if(got<=0){
if (errno == EAGAIN){
//what to do?
}else{
perror("tcp to sctp send error");
}
}
else{
pos += got;}
}
}
經過一些讀/寫后,我的sctp_sendmsg返回EAGAIN,這意味着sctp發送緩沖區已滿。 如何處理這種情況而不會丟失從fd_server套接字讀取的數據?
您需要為每個fd_client套接字保留某種“上下文”(數據結構)。 對於連接到服務器的每個新客戶端套接字,創建“連接狀態”結構的實例並將其存儲在哈希表中。 這將類似於以下內容:
struct ConnectionState
{
int fd_client; // socket
uint8_t buffer[MAX_CHUNK_SIZE]; // protocol buffer for this connection
int buffer_length; // how many bytes received into this buffer
int pos; // how many bytes transmitted back out on fd_client from "buffer"
int has_data; // boolean to indicate protocol state (1 if there's still data in buffer to send)
};
如果無法一次發送所有內容,請在epoll模式下將fd_client套接字從EPOLLIN切換到EPOLLOUT。 在ConnectionState結構中將“ has_data”更改為true。 然后返回等待套接字事件。 當您能夠再次發送時,請查看該套接字的ConnectionState結構,以確定是否仍然需要繼續發送或接收新緩沖區。
注意邊緣觸發式插座。 當您從EPOLLOUT過渡回EPOLLIN時,您需要繼續並再次recv()只是為了確保您不會丟失任何數據。 (類似地,要進入發送狀態,請嘗試初始發送)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.