0

我写了一个代理,它也复制流量。我正在尝试将网络流量复制到应接收所有输入并处理所有请求的副本服务器。然而,只有主服务器上的响应对客户端可见。高级工作流程如下

Thread 1. Take input from client forward it to a pipe in non-blocking way, and to the server
Thread 2. Read from server and send to client
Thread 3. Read from pipe and forward to replica server
Thread 4. Read from replica server and drop

代码可在此要点中找到:https ://gist.github.com/nipunarora/679d49e81086b5a75195ec35ced646de

该测试似乎适用于较小的数据和事务,但在使用 iperf 和较大的数据集时,我似乎遇到了以下错误:

Buffer overflow? : Resource temporarily unavailable

问题出在代码中的特定部分:

void forward_data_asynch(int source_sock, int destination_sock) {
  char buffer[BUF_SIZE];
  int n;

  //put in error condition for -1, currently the socket is shutdown
  while ((n = recv(source_sock, buffer, BUF_SIZE, 0)) > 0)// read data from input socket 
    { 
      send(destination_sock, buffer, n, 0); // send data to output socket
      if( write(pfds[1],buffer,n) < 0 )//send data to pipe
        {
          //fprintf(stats_file,"buffer_overflow \n");
          //printf("format string" ,a0,a1);
          //int_timeofday();
          perror("Buffer overflow? ");
        }
      //DEBUG_PRINT("Data sent to pipe %s \n", buffer);
    }

  shutdown(destination_sock, SHUT_RDWR); // stop other processes from using socket
  close(destination_sock);

  shutdown(source_sock, SHUT_RDWR); // stop other processes from using socket
  close(source_sock);
}

阅读过程如下:

void forward_data_pipe(int destination_sock) {

  char buffer[BUF_SIZE];
  int n;
  sleep(10);
  //put in error condition for -1, currently the socket is shutdown
  while ((n = read(pfds[0], buffer, BUF_SIZE)) > 0)// read data from pipe socket 
    { 
      //sleep(1);
      //DEBUG_PRINT("Data received in pipe %s \n", buffer);
      send(destination_sock, buffer, n, 0); // send data to output socket
    }

  shutdown(destination_sock, SHUT_RDWR); // stop other processes from using socket
  close(destination_sock);
}

请注意,管道已定义如下:

/**   Make file descriptor non blocking */
int setNonblocking(int fd)
{
  int flags;

  /* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
  /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
  if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
    flags = 0;
  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
  /* Otherwise, use the old way of doing it */
  flags = 1;
  return ioctl(fd, FIOBIO, &flags);
#endif
}   

任何人都可以帮助解决错误的原因吗?

4

1 回答 1

0

您的问题是数据发送到已设置为非阻塞模式的套接字的速度太快。你有几个选择:

  1. 接受数据可能丢失的事实。如果您不想延迟主服务器上的处理,这是您唯一的选择。
  2. 不要将套接字设置为非阻塞模式。如果您不想丢失数据,默认模式(阻塞)似乎更适合您的应用程序。但是,这也意味着系统可能会变慢。
  3. 使用 poll()、select()、kqueue()、epoll()、/dev/poll 或类似方法等待套接字有足够的可用缓冲区空间。但是,在使用它时,您应该考虑为什么要首先将套接字设置为非阻塞模式,如果您仍然想阻塞它。这也导致系统变慢。
于 2017-03-05T10:25:24.700 回答