本文介绍了的Winsock recvfrom的设置超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个阻塞套接字后试图给recvfrom()的端口16毫秒超时。平台是Windows。我在万吨的例子在网上看了,似乎很简单我只是似乎无法得到它的工作。任何帮助将是AP preciated!

 的#include< winsock2.h>
#包括LT&;串GT;的#pragma评论(LIB,WS2_32.LIB)#定义PORT_NUM 8001INT主要(无效)
{
  标准::字符串localIP;
  SOCKADDR_IN localAddr;
  SOCKADDR_IN remoteAddr;
  hostent *本地主机;
  字符缓冲区[1024];
  WSADATA wsData;  INT结果=调用WSAStartup(MAKEWORD(2,2),放大器; wsData); // winsock的第2版  本地主机=的gethostbyname();
  localIP = INET_NTOA(*(in_addr结构*)* localhost-> h_addr_list);  localAddr.sin_family = AF_INET;
  localAddr.sin_port = htons(PORT_NUM); //设定的端口号
  localAddr.sin_addr.s_addr = inet_addr(localIP.c_str()); //设置IP地址  INT mHandle = WSASocket(AF_INET,SOCK_DGRAM,IPPROTO_UDP,NULL,0,0);  如果(mHandle == INVALID_SOCKET)
    返回1;
  如果(绑定(mHandle,(SOCKADDR *)及localAddr,sizeof的(localAddr))== SOCKET_ERROR)
    返回1;  的timeval电视;
  tv.tv_sec = 0;
  tv.tv_usec = 1600;    //为recv调用设置超时
  如果(setsockopt的(mHandle,SOL_SOCKET,SO_RCVTIMEO,
                reinter pret_cast<字符*>(安培;电视)的sizeof(timeval中)))
    返回1;  INT长度= sizeof的(remoteAddr);  //< - 在这里永远块
  recvfrom的(mHandle,缓冲器,1024,0,(SOCKADDR *)及remoteAddr,&放大器;长度);  返回0;
}/ *我也试过路过的时候,像这样:
诠释毫秒= 16;如果(setsockopt的(mHandle,SOL_SOCKET,SO_RCVTIMEO,reinter pret_cast<字符*>(安培; MS)的sizeof(INT)))
  返回1; * /


解决方案

我看着select函数和劳拉说我应该做的,并得到了它真正轻松地工作!谢谢!

  FD_SET FDS;
INT N;
timeval结构电视;//设置文件描述符集。
FD_ZERO(安培; FDS);
FD_SET(mHandle,&安培; FDS);//设置了超时的timeval结构。
tv.tv_sec = 10;
tv.tv_usec = 0;//等到超时或接收的数据。
N =选择(mHandle,&安培; FDS,NULL,NULL,&安培;电视);
如果(N == 0)
{
  的printf(超时.. \\ n);
  返回0;
}
否则,如果(N == -1)
{
  的printf(错误.. \\ n);
  返回1;
}INT长度= sizeof的(remoteAddr);recvfrom的(mHandle,缓冲器,1024,0,(SOCKADDR *)及remoteAddr,&放大器;长度);

I'm trying to set up a blocking socket to timeout after 16 ms of trying to recvfrom() on a port. Platform is Windows. I've looked at tons of examples online and it seems really simple I just can't seem to get it to work. Any help would be appreciated!

#include <winsock2.h>
#include <string>

#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<char*>(&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<char*>(&ms), sizeof(int)))
  return 1; */
解决方案

I looked into the select function and as laura said I should do and got it to work real easily! Thanks!

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);

这篇关于的Winsock recvfrom的设置超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 11:47
查看更多