簡體   English   中英

設計具有無阻塞管道轉發到另一台服務器的代理

[英]Designing a proxy with non-blocking pipe forwarding to another server

我寫了一個代理,它也重復流量。 我正在嘗試將網絡流量復制到副本服務器,該副本服務器應接收所有輸入並還要處理所有請求。 但是,客戶端只能看到主服務器上的響應。 高級工作流程如下

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
}   

任何人都可以幫助解決錯誤的原因嗎?

您遇到的問題是數據發送到設置為非阻塞模式的套接字的速度太快了。 您有幾種選擇:

  1. 接受數據可能會丟失的事實。 如果您不想延遲主服務器上的處理,這是您唯一的選擇。
  2. 不要將套接字設置為非阻塞模式。 如果您不希望丟失數據,則默認模式“阻止”似乎更適合您的應用程序。 但是,這也意味着系統可能會變慢。
  3. 使用poll(),select(),kqueue(),epoll(),/ dev / poll或類似方法,等待套接字具有足夠的可用緩沖區空間。 但是,在使用此功能時,您應該考慮為什么要在套接字上首先將其設置為非阻塞模式。 這也導致系統變慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM