0

我有以下情况。我的服务器从远程服务器(fd_server)接收数据并将其转发给客户端(fd_client)。我正在使用边缘触发的 epoll,因此我可以处理多个客户端和多个服务器连接。

程序:

  1. 客户端连接到服务器。
  2. 我的服务器连接到远程服务器并请求数据。
  3. 远程服务器响应,我的服务器将数据转发给客户端。

细节:

在我的服务器连接到远程服务器后,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;}
    }
}
4

1 回答 1

0

经过一些读/写后,我的 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() 以确保您不会丢失任何数据。(同理进入发送状态,尝试初始发送)。

于 2013-01-22T10:58:48.997 回答