TCP 代理接收数据阻塞问题解决方案

TCP 代理转发数据示意图如下:

                 Client <--------------------------->TCP Proxy <---------------------------->Server

Client 先发起请求,代理在接收到connect 请求之后,新建一个线程处理该客户端的转发需求。

在调用recv 接收数据时,有时程序会一直阻塞在那里,原因是socket 默认是阻塞模式,而当前没有数据可接收时会一直等待。还有另一个情况:调用一次recv, 数据并没有接收完全,再调用recv 时仍然会阻塞。在应用层除非明确知道结束标志或者数据长度,否则没法知道数据是否已接收完毕。

 

正确的做法是轮询,使用select 实现,当某个socket处于可以接收时,就去读取数据,然后用另一个socket 转发。

实现的方法:

fd_set readfds;

TIMEVAL tv;

tv.tv_usec = 100;

tv.tv_sec = 1;

do{

    FD_ZERO(&readfds);

    FD_SET(socket_client, &readfds);

    FD_SET(socket_server, &readfds);

    int n = select(0, &readfds, NULL, NULL, &tv);

    if (n>0)  //有数据可读
    {
        if (FD_ISSET(socket_client, &readfds))
        {

            int nr = recv(socket_client, buffer, buffer_size, 0);

            if (nr > 0)

                int ns = send(socket_server, buffer, nr, 0);
        }

     
        if (FD_ISSET(socket_server, &readfds))
        {
            int nr = recv(socket_server, buffer, buffer_size, 0);
            if (nr > 0)
                int ns = send(socket_client, buffer, nr, 0);

        }
    }

    else if (n == SOCKET_ERROR) //选择错误
    { 
         printf("select error");
         break;
    }

    else  //超时,Sleep 1s
    {
        Sleep(1000);
    }

}while(true);

参考:

https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值