Linux的程序如下:errno = EAGAIN;
n = -1;
for (i = 0; errno == EAGAIN && i <= TIMEOUT && n < 0; i++)
 {
n = recvfrom (sock, recvbuf, sizeof (recvbuf), MSG_DONTWAIT,
(struct sockaddr *) &ack, (socklen_t *) & server_len);
usleep (1000);
  }
请教:1、EAGAIN 宏在VC中没定义,我自已定义:#define EAGAIN 11 可否?或应该替换成什么值?
2、 MSG_DONTWAIT在VC中没定义,应该换成什么?--我换成MSG_PEEK,结果在Linux可以成功传送文件的程序,在Windows下运行出错
请高手解答,谢谢!

解决方案 »

  1.   

    1、可以
    2、
    recvfrom
    The Windows Sockets recvfrom function receives a datagram and stores the source address.int recvfrom (
      SOCKET s,                   
      char FAR* buf,              
      int len,                    
      int flags,                  
      struct sockaddr FAR* from,  
      int FAR* fromlen            
    );
     
    Parameters

    [in] A descriptor identifying a bound socket. 
    buf 
    [out] A buffer for the incoming data. 
    len 
    [in] The length of buf. 
    flags 
    [in] An indicator specifying the way in which the call is made. 
    from 
    [out] An optional pointer to a buffer that will hold the source address upon return. 
    fromlen 
    [in/out] An optional pointer to the size of the from buffer. 
    Res
    The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which the data was sent. The socket must not be connected. The local address of the socket must be known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications. For client applications using this function, the socket can become bound implicitly to a local address through sendto, WSASendTo, or WSAJoinLeaf.For stream oriented sockets such as those of type SOCK_STREAM, a call to recvfrom returns as much information as is currently available—up to the size of the buffer supplied. If the socket has been configured for in-line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is yet unread, only out-of-band data will be returned. The application can use the ioctlsocket or WSAIoctl SIOCATMARK command to determine whether any more out-of-band data remains to be read. The from and fromlen parameters are ignored for connection-oriented sockets.For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer supplied. If the datagram or message is larger than the buffer supplied, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.If the from paramter is nonzero and the socket is not connection oriented, (type SOCK_DGRAM for example), the network address of the peer that sent the data is copied to the corresponding SOCKADDR structure. The value pointed to by fromlen is initialized to the size of this structure and is modified, on return, to indicate the actual size of the address stored in the SOCKADDR structure.If no incoming data is available at the socket, the recvfrom function blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect can be used to determine when more data arrives.If the socket is connection oriented and the remote side has shut down the connection gracefully, the call to recvfrom will complete immediately with zero bytes received. If the connection has been reset recvfrom will fail with the error WSAECONNRESET.The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing the following values:Value Meaning 
    MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue, and the function returns the number of bytes currently pending to receive. 
    MSG_OOB Process out-of-band data. (See section DECnet Out-Of-band data for a discussion of this topic.) 
    Return Values
    If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.Error Codes
    WSANOTINITIALISED A successful WSAStartup must occur before using this function. 
    WSAENETDOWN The network subsystem has failed. 
    WSAEFAULT The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address. 
    WSAEINTR The (blocking) call was canceled through WSACancelBlockingCall. 
    WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. 
    WSAEINVAL The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative. 
    WSAEISCONN The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless. 
    WSAENETRESET The connection has been broken due to the "keep-alive" activity detecting a failure while the operation was in progress. 
    WSAENOTSOCK The descriptor is not a socket. 
    WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations. 
    WSAESHUTDOWN The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH. 
    WSAEWOULDBLOCK The socket is ed as nonblocking and the recvfrom operation would block. 
    WSAEMSGSIZE The message was too large to fit into the specified buffer and was truncated. 
    WSAETIMEDOUT The connection has been dropped, because of a network failure or because the system on the other end went down without notice. 
    WSAECONNRESET The virtual circuit was reset by the remote side executing a "hard" or "abortive" close. The application should close the socket as it is no longer usable. On a UDP datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message. 
    QuickInfo
      Windows NT: Yes
      Windows: Yes
      Windows CE: Use version 1.0 and later.
      Header: Declared in winsock2.h.
      Import Library: Link with ws2_32.lib.
      

  2.   

    1、不可以。errno是为兼容C而保留的全局量,是由OS在API出错时设置的错误码。你应该看看EAGAIN 在WINDOWS中的等价定义;2、MSG_DONTWAIT从字面意思来理解可能为延时处理,在WINDOWS中有个超时设置,设为“0”即可。(如果理解错误请指正)。
      

  3.   

    1、就是想问EAGAIN 在WINDOWS中的等价定义
    2、DONTWAIT应该是不延时吧?WINDOWS有没有等价的定义?--MSDN好像没看到说明
      

  4.   

    、EAGAIN 宏在VC中没定义,我自已定义:#define EAGAIN 11 可否?或应该替换成什么值? recvfrom(经socket接收数据)  
    相关函数  recv,recvmsg,send,sendto,socket 
    表头文件  #include<sys/types.h> 
    #include<sys/socket.h> 
     
    定义函数  int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *fromlen); 
     
    函数说明  recv()用来接收远程主机经指定的socket 传来的数据,并把数据存到由参数buf 指向的内存空间,参数len 为可接收数据的最大长度。参数flags 一般设0,其他数值定义请参考recv()。参数from用来指定欲传送的网络地址,结构sockaddr 请参考bind()。参数fromlen为sockaddr的结构长度。 
     
    返回值  成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。 
     
    错误代码  EBADF 参数s非合法的socket处理代码 
    EFAULT 参数中有一指针指向无法存取的内存空间。 
    ENOTSOCK 参数s为一文件描述词,非socket。 
    EINTR 被信号所中断。 
    EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断。 
    ENOBUFS 系统的缓冲内存不足 
    ENOMEM 核心内存不足 
    EINVAL 传给系统调用的参数不正确。 2、 MSG_DONTWAIT在VC中没定义,应该换成什么?--我换成MSG_PEEK,结果在Linux可以成功传送文件的程序,在Windows下运行出错 
     
    采用了MSG_DONTWAIT标志,它的作用是告诉recv()函数如果有数据到来的话就接受全部数据并立刻返回,没有数据的话也是立刻返回,而不进行任何的等待
    lz可以按照非阻塞的select接收数据...不必改它的代码,看懂意思自己做..
      

  5.   

    1、EAGAIN 宏在VC中没定义,我自已定义:#define EAGAIN 11 可否?或应该替换成什么值? 
    ================================
    不可以,这个要根据EAGAIN在linux系统中的系统码的意义来定义,同样的系统码 11在linux/windows里面是不同的概念.
    所以找到代表同样功能的系统码替换可以,不可以自己定义2、 MSG_DONTWAIT在VC中没定义,应该换成什么?--我换成MSG_PEEK,结果在Linux可以成功传送文件的程序,在Windows下运行出错 
    参看recvfrom函数的定义.在msdn里面.做vc 要学会看msdn是必须的,否则寸步难行
      

  6.   

    按照代码逻辑意思去做啊  winsock和 linux socket没什么太大的区别的recvfrom 阻塞去读不就行了么 非得按照linux的做法?
      

  7.   

    一般来说不同操作系统的系统软件开发,不同的地方就是系统调用.比如windows的setsockopt系统调用和linux的系统调用,虽然函数名字一样.但是里面的参数,以及参数宏的意义是不同的.所以在这类调用的地方尽量使用判断宏比如#if _linux_
    setsockopt(...); // linux系统下
    #elif
    setsockopt(...);  //windows系统下
    #endif由于这个函数在不同操作系统setsockopt函数的参数意义不同.也就是说通常来说我们会传递一个宏定义进去代表不同的命令.但是这个宏定义在windows可能定义为0x0080在linux下可能是0x0081,所以这个地方就要对开发的操作系统进行分类.确保宏定义所代表的系统码是当前系统的系统码.否则会出现奇怪的错误而自己却找不到.
      

  8.   

    请具体说说怎么设置flag那一项的参数?
    我现在碰到新的问题是这样子的:
    http://topic.csdn.net/u/20080416/17/acd7e054-b936-4286-81ae-ffad2839962f.html?seed=2107128658
    两边都给分了,问题解决就结贴,请高手指点,谢谢!
      

  9.   

    1、不可以。EAGAIN 在WINDOWS中的等价定义为WSAEWOULDBLOCK; 2、在windows中可采用先select,如果可读再调用recvfrom,虽然recf是阻塞的,但select可以不阻塞
      

  10.   

    Linux<——>Windows
    EAGAIN(EWOULDBLOCK)<——>WSAEWOULDBLOCK
    MSG_DONTWAIT<——>MSG_PARTIAL