通过睡眠控制吞吐量

时间:2010-12-09 18:17:29

标签: c++ algorithm sockets networking buffer

我有这个代码,重点是我希望使用UDP套接字接收不超过600Kbits / s,我使用持续时间和接收睡眠命令来实现算法....

#if defined (WIN32)
#include <winsock2.h>

typedef int socklen_t;
#elif defined (linux)
#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif

#include <stdio.h>

#include <stdlib.h>

#include <time.h>


 #define RCVBUFSIZE 4
#define PORT 4444
 #define ECHOMAX 255

int main(void)
 {
#if defined (WIN32)
    WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
#else
    int erreur = 0;
#endif

int recvMsgSize;
char echoBuffer[RCVBUFSIZE];
//unsigned int echoStringLen;
//int bytesRcvd, totalBytesRcvd; //bytes received in a single recv()

SOCKET sock;
SOCKADDR_IN sin;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);


if(!erreur)
{

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_family = AF_INET;
    sin.sin_port = htons(4444);
   memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero));

     bind(sock, (SOCKADDR*)&sin, sizeof(sin));

//totalBytesRcvd = 0;

printf("Received: ");

int speed_limit= 614400; //600Kbits/s
int one_second=1000;
int elapsed; //elapsed time
int transmit=0; // how much i receive during 'elapsed'
int expected_receive; //what I'm excpected to receive
int transmit_delta; //diference
int time_sleep; //how much to sleep
clock_t start_time= clock();

 for(;;)
{


    if((recvMsgSize=recvfrom(sock, echoBuffer,1024, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize)) > 0)
    {
            transmit+=recvMsgSize;
            clock_t tempo= clock();

            elapsed=(tempo-start_time)/CLOCKS_PER_SEC;
        // Check moment speed every five second, you can choose any value
            if(elapsed>5)
            {
                start_time= tempo;
                expected_receive=speed_limit*elapsed/8;
                transmit_delta=expected_receive-transmit;

                if(transmit_delta>0)
                {
                    time_sleep=8*transmit_delta*one_second/speed_limit;
                    Sleep(time_sleep);
                }
                transmit=0;
            }
            echoBuffer[recvMsgSize]='\0';
            printf(echoBuffer);


    }

}
    printf("\n");
    getchar() ;

closesocket(sock);

    #if defined (WIN32)
        WSACleanup();
    #endif
}

return EXIT_SUCCESS;
}

问题是它收到消息但是它不时地阻止接收过程...我猜这会导致数据丢失,尤其是当我使用UDP时......

任何替代方案都是welcolme ......

提前感谢..

3 个答案:

答案 0 :(得分:1)

最好不要睡觉 - 只要在超过阈值时读取并丢弃数据,然后在准备好后再继续处理(间隔期满后)。

答案 1 :(得分:1)

如果数据是通过UDP到达的,则无法降低接收端的吞吐量。你必须告诉发送计算机发送更少的数据。接收方唯一的选择是接收UDP数据包,或者让它们被丢弃,然后对它们做一些事情。

如果您使用TCP,那么TCP协议包含一个内置的方法来执行您想要的操作(称为“源猝灭”)...接收方的TCP协议层将向发送方发送消息告知发送方如果接收器出现问题,请放慢速度。 (如果你愿意的话,你可以通过比平时更慢地读取数据来影响“接收器是否有跟上问题”。

答案 2 :(得分:0)

如果您使用带有select()的非阻塞套接字,您可以忽略这些数据,直到您准备好阅读它为止。不读取数据将导致TCP连接“减速”。但是,通过这种方式,可以准确控制收到的数据量。这只是一个近似值。我所知道的所有以更准确的方式限制带宽的技术都是在发送方实现的。