读书人

100分!Windows上sendto()发送UDP数

发布时间: 2012-10-09 10:21:45 作者: rapoo

100分!!!Windows下sendto()发送UDP数据包 sleep()问题。
在一个线程里面通过sendto()函数发送数据,通过sleep()控制发送频率,休眠时间为2毫秒,开始发送数据时间间隔大约2毫秒,运行一段时间后,发送间隔变为15毫秒左右,在2台机器上都有此问题,请问各位大大这是什么问题呢?将socket设置为非阻塞还是不行!2个周了,头疼啊!求高手指点!!!

[解决办法]
发送间隔变为15毫秒左右
------------------
sleep精度就那么高。。。
[解决办法]
1. sleep 换成timer试试
2,让CPU空转,直到过了2ms

C/C++ code
while(true) {  set last time   do  {    //dummy operations;    ....      ]while(curentTime - lastTime > 2ms);    send to }
[解决办法]
Q:代码就是在线程里面,读取文件,通过sleep()控制读取速度,
A:从你的描述看使用的是阻塞socket,这没办法精确控制时间,因为recv在对方没有数据时,会一直阻塞.
建议:使用非阻塞socket或异步socket,这里有一些源码请参考,非阻塞socket看MsgSndClnt,异步socket看Finger. 来自《WinSock网络编程经络》,源码下载地址:http://download.csdn.net/detail/geoff08zhang/4571358
[解决办法]
用SOCKET的超时做延迟。
C/C++ code
#include <time.h>#include <sys/stat.h>#include <stdarg.h>#include <direct.h>#include <io.h>#include <dos.h>#include <WinSock2.h>#include <windows.h>#define socklen_t int#include "Afx.h"class CSleepTimeout{private:    int        m_sock;public:    CSleepTimeout ()    {        m_sock = -1;            WSADATA sockData;        WSAStartup (MAKEWORD (2, 2), &sockData);        init();    }        //析构函数    virtual ~CSleepTimeout ()    {        if (m_sock != -1)        {            closesocket(m_sock);            m_sock = -1;        }        WSACleanup();            }        //等待超时:单位us(微秒)    int Sleep(long time_out=1)    {        if(time_out>0)        {            fd_set readfds;            FD_ZERO(&readfds);            FD_SET(m_sock, &readfds);            struct timeval  authtime;            authtime.tv_usec = time_out;            authtime.tv_sec = (long)0L;                    if(select(m_sock+1,&readfds,NULL,NULL,&authtime) < 0)                return 0;        }        return 1;    }        //初始化    int init()    {        m_sock = socket (AF_INET, SOCK_DGRAM, 0);        if (m_sock == -1)            return 0;            struct sockaddr_in m_SockAddr;            m_SockAddr.sin_family = AF_INET;        m_SockAddr.sin_port = htons(0);            m_SockAddr.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");                int opt = 1;//opt必须为整数,否则linux下会失败        if (setsockopt (m_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(int)) == -1)            return 0;        int ret=bind(m_sock, (struct sockaddr*)&m_SockAddr,sizeof(m_SockAddr));        if(ret == -1)            return 0;        return 1;    }};
[解决办法]
建议用select来实现定时,sleep很不精确
[解决办法]
GetTickCount,调用系统时间试试。

或者写个循环代替
[解决办法]
sleep的精度问题,还有就是你统计时间的函数精度问题,反正就这两种。

读书人网 >C++

热点推荐