gpt4 book ai didi

c - 设计一个具有非阻塞管道转发到另一台服务器的代理

转载 作者:行者123 更新时间:2023-11-30 16:49:22 24 4
gpt4 key购买 nike

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

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 或类似方法等待套接字有足够的可用缓冲区空间。但是,在使用此功能时,如果您仍然想阻止套接字,则应该首先考虑为什么将套接字设置为非阻塞模式。这也会导致系统速度变慢。

关于c - 设计一个具有非阻塞管道转发到另一台服务器的代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42605232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com