当前位置:  开发笔记 > 编程语言 > 正文

设置winsock recvfrom的超时时间

如何解决《设置winsockrecvfrom的超时时间》经验,为你挑选了3个好方法。

我试图设置一个阻塞套接字,在尝试端口上的recvfrom()16 ms后超时.平台是Windows.我在网上看了很多例子,看起来很简单,我似乎无法让它发挥作用.任何帮助,将不胜感激!

#include 
#include 

#pragma comment(lib, "ws2_32.lib")

#define PORT_NUM 8001

int main(void)
{
  std::string localIP;
  sockaddr_in localAddr;
  sockaddr_in remoteAddr;
  hostent* localhost;
  char buffer[1024];
  WSADATA wsData;

  int result = WSAStartup(MAKEWORD(2,2), &wsData);  // winsock version 2

  localhost = gethostbyname("");
  localIP   = inet_ntoa(*(in_addr*)*localhost->h_addr_list);

  localAddr.sin_family       = AF_INET;
  localAddr.sin_port         = htons(PORT_NUM);             // Set Port Number
  localAddr.sin_addr.s_addr  = inet_addr(localIP.c_str());  // Set IP Address

  int mHandle = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);

  if(mHandle == INVALID_SOCKET)
    return 1;


  if(bind(mHandle, (SOCKADDR*)&localAddr, sizeof(localAddr)) == SOCKET_ERROR)
    return 1;

  timeval tv;
  tv.tv_sec  = 0;
  tv.tv_usec = 1600;

    // Set Timeout for recv call
  if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO, 
                reinterpret_cast(&tv), sizeof(timeval)))
    return 1;

  int length = sizeof(remoteAddr);

  // <-- Blocks here forever
  recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length);  

  return 0;
}

/*  I've also tried passing the time like so:
int ms = 16;

if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&ms), sizeof(int)))
  return 1; */

Cory Carlson.. 24

我查看了select函数,并且laura说我应该这样做,让它很容易实现!谢谢!

fd_set fds ;
int n ;
struct timeval tv ;

// Set up the file descriptor set.
FD_ZERO(&fds) ;
FD_SET(mHandle, &fds) ;

// Set up the struct timeval for the timeout.
tv.tv_sec = 10 ;
tv.tv_usec = 0 ;

// Wait until timeout or data received.
n = select ( mHandle, &fds, NULL, NULL, &tv ) ;
if ( n == 0)
{ 
  printf("Timeout..\n");
  return 0 ;
}
else if( n == -1 )
{
  printf("Error..\n");
  return 1;   
}

int length = sizeof(remoteAddr);

recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length); 


joseAndresGo.. 15

我通过像下面的那样传递它来尝试它

     int iTimeout = 1600;
     iRet = setsockopt( pSapManager->m_cSocket,
                        SOL_SOCKET,
                        SO_RCVTIMEO,
                        /*
                        reinterpret_cast(&tv),
                        sizeof(timeval) );
                        */
                        (const char *)&iTimeout,
                        sizeof(iTimeout) );

并运行它!



1> Cory Carlson..:

我查看了select函数,并且laura说我应该这样做,让它很容易实现!谢谢!

fd_set fds ;
int n ;
struct timeval tv ;

// Set up the file descriptor set.
FD_ZERO(&fds) ;
FD_SET(mHandle, &fds) ;

// Set up the struct timeval for the timeout.
tv.tv_sec = 10 ;
tv.tv_usec = 0 ;

// Wait until timeout or data received.
n = select ( mHandle, &fds, NULL, NULL, &tv ) ;
if ( n == 0)
{ 
  printf("Timeout..\n");
  return 0 ;
}
else if( n == -1 )
{
  printf("Error..\n");
  return 1;   
}

int length = sizeof(remoteAddr);

recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length); 



2> joseAndresGo..:

我通过像下面的那样传递它来尝试它

     int iTimeout = 1600;
     iRet = setsockopt( pSapManager->m_cSocket,
                        SOL_SOCKET,
                        SO_RCVTIMEO,
                        /*
                        reinterpret_cast(&tv),
                        sizeof(timeval) );
                        */
                        (const char *)&iTimeout,
                        sizeof(iTimeout) );

并运行它!



3> shawn..:

WINDOWS:超时值是一个DWORD(以毫秒为单位),传递给setsockopt()的地址是const char*

LINUX:Timeout值是一个struct timeval,传递给setsockopt()的地址是const void*

资料来源:http://forums.codeguru.com/showthread.php?t = 353217

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有