recv 函数 (winsock.h)

您所在的位置:网站首页 recv返回-1 recv 函数 (winsock.h)

recv 函数 (winsock.h)

#recv 函数 (winsock.h)| 来源: 网络整理| 查看: 265

recv 函数 (winsock.h) 项目 03/15/2023

recv 函数从连接的套接字或绑定的无连接套接字接收数据。

语法 int recv( [in] SOCKET s, [out] char *buf, [in] int len, [in] int flags ); 参数

[in] s

标识连接的套接字的描述符。

[out] buf

指向用于接收传入数据的缓冲区的指针。

[in] len

buf 参数指向的缓冲区的长度(以字节为单位)。

[in] flags

一组影响此函数行为的标志。 请参阅下面的备注。 有关此参数可能值的详细信息,请参阅“备注”部分。

返回值

如果未发生错误, recv 将返回收到的字节数, buf 参数指向的缓冲区将包含接收的此数据。 如果连接已正常关闭,则返回值为零。

否则,将返回SOCKET_ERROR值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

错误代码 含义 WSANOTINITIALISED 在使用此函数之前,必须执行成功的 WSAStartup 调用。 WSAENETDOWN 网络子系统失败。 WSAEFAULT buf 参数未完全包含在用户地址空间的有效部分。 WSAENOTCONN 套接字未连接。 WSAEINTR (阻止) 调用通过 WSACancelBlockingCall 取消。 WSAEINPROGRESS 正在执行阻止的 Windows 套接字 1.1 调用,或者服务提供商仍在处理回调函数。 WSAENETRESET 对于面向连接的套接字,此错误表示连接已中断,因为 活动 在操作正在进行时检测到失败。 对于数据报套接字,此错误显示生存时间已经过期。 WSAENOTSOCK :描述符不是套接字。 WSAEOPNOTSUPP MSG_OOB已指定,但套接字不是流式传输样式(例如类型SOCK_STREAM),与此套接字关联的通信域中不支持 OOB 数据,或者套接字是单向的,并且仅支持发送操作。 WSAESHUTDOWN 套接字已关闭;关闭后无法在套接字上接收,其方式设置为SD_RECEIVE或SD_BOTH。 WSAEWOULDBLOCK 套接字标记为非阻止,接收操作将阻止。 WSAEMSGSIZE 消息太大,无法放入指定的缓冲区,并且已被截断。 WSAEINVAL 该套接字 未绑定绑定,或者指定了未知标志,或者为启用了SO_OOBINLINE的套接字指定了MSG_OOB,或者只为字节流套接字指定了 (,) len 为零或负。 WSAECONNABORTED 由于超时或其他故障,虚拟线路已终止。 因为套接字不可再用,应用程序应关闭套接字。 WSAETIMEDOUT 因为网络故障或对等系统无法响应,已经丢弃了连接。 WSAECONNRESET 执行硬性或异常关闭的远程端重置了虚拟线路。 因为套接字不可再用,应用程序应关闭套接字。 在 UDP 数据报套接字上,此错误指示以前的发送操作导致 ICMP“端口不可访问”消息。 注解

recv 函数用于读取面向连接的套接字或无连接套接字上的传入数据。 使用面向连接的协议时,必须在调用 recv 之前连接套接字。 使用无连接协议时,必须在调用 recv 之前绑定套接字。

套接字的本地地址必须已知。 对于服务器应用程序,请使用显式 绑定 函数或隐式 接受 或 WSAAccept 函数。 客户端应用程序不建议显式绑定。 对于客户端应用程序,套接字可以使用 connect、 WSAConnect、 sendto、 WSASendTo 或 WSAJoinLeaf 隐式绑定到本地地址。

对于连接套接字或无连接套接字, recv 函数限制接收消息的地址。 该函数仅从连接中指定的远程地址返回消息。 其他地址的邮件 (被无提示) 丢弃。

对于面向连接的套接字, (类型SOCK_STREAM例如) ,调用 recv 将返回当前可用的数据量(最大为指定缓冲区的大小)。 如果套接字已配置为对 OOB 数据进行内联接收, (套接字选项SO_OOBINLINE) 且 OOB 数据尚未读取,则仅返回 OOB 数据。 应用程序可以使用 ioctlsocket 或 WSAIoctlSIOCATMARK 命令来确定是否要读取更多 OOB 数据。

对于无连接套接字 (类型SOCK_DGRAM或其他面向消息的套接字) ,数据是从 连接 函数指定的目标地址 (消息) 提取的第一个排队数据报。

如果数据报或消息大于指定的缓冲区,则缓冲区将填充数据报的第一部分,并 重新生成 错误 WSAEMSGSIZE。 例如,对于不可靠的协议 (,UDP) 多余的数据丢失;对于可靠的协议,数据由服务提供商保留,直到通过调用足够大的缓冲区 的 recv 成功读取数据。

如果套接字上没有可用的传入数据, 则 recv 调用会阻止数据,并等待数据根据为 WSARecv 定义的阻止规则(未设置MSG_PARTIAL标志)到达,除非套接字未阻止。 在这种情况下,返回一个值SOCKET_ERROR,错误代码设置为 WSAEWOULDBLOCK。 选择、WSAAsyncSelect 或 WSAEventSelect 函数可用于确定何时到达更多数据。

如果套接字面向连接,并且远程端已正常关闭连接,并且已接收所有数据, 则 recv 将立即完成,并接收零字节。 如果连接已重置, 则 recv 将失败并出现 WSAECONNRESET 错误。

标志参数可用于影响函数调用的行为,这些行为超出了为关联套接字指定的选项。 此函数的语义由套接字选项和 标志 参数确定。 标志 参数的 可能值是使用以下任一值的按位 OR 运算符构造的。

Value 含义 MSG_PEEK 查看传入数据。 数据将复制到缓冲区中,但不会从输入队列中删除。 MSG_OOB 处理带外 (OOB) 数据。 MSG_WAITALL 仅当发生以下事件之一时,接收请求才会完成: 调用方提供的缓冲区已完全满。 该连接已关闭。 请求已被取消或出错。 请注意,如果基础传输不支持MSG_WAITALL,或者套接字处于非阻塞模式,则此调用将失败并出现 WSAEOPNOTSUPP。 此外,如果指定了MSG_WAITALL以及MSG_OOB、MSG_PEEK或MSG_PARTIAL,则此调用将失败并出现 WSAEOPNOTSUPP。 数据报套接字或面向消息的套接字不支持此标志。   注意 发出阻止 Winsock 调用(如 recv)时,Winsock 可能需要等待网络事件,然后才能完成呼叫。 在这种情况下,Winsock 会执行可警报的等待,这可以通过异步过程调用 (APC) 在同一线程上计划的异步过程调用中断。 在同一线程上中断持续阻塞 Winsock 调用的 APC 中发出另一个阻止 Winsock 调用将导致未定义的行为,并且永远不会由 Winsock 客户端尝试。   示例代码 下面的代码示例演示 了 recv 函数的使用。 #define WIN32_LEAN_AND_MEAN #include #include #include // Link with ws2_32.lib #pragma comment(lib, "Ws2_32.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int __cdecl main() { //---------------------- // Declare and initialize variables. WSADATA wsaData; int iResult; SOCKET ConnectSocket = INVALID_SOCKET; struct sockaddr_in clientService; char *sendbuf = "this is a test"; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; //---------------------- // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != NO_ERROR) { printf("WSAStartup failed: %d\n", iResult); return 1; } //---------------------- // Create a SOCKET for connecting to server ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError() ); WSACleanup(); return 1; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port of the server to be connected to. clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" ); clientService.sin_port = htons( 27015 ); //---------------------- // Connect to server. iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ); if ( iResult == SOCKET_ERROR) { closesocket (ConnectSocket); printf("Unable to connect to server: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } // Send an initial buffer iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 ); if (iResult == SOCKET_ERROR) { printf("send failed: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } printf("Bytes Sent: %ld\n", iResult); // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } // Receive until the peer closes the connection do { iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); if ( iResult > 0 ) printf("Bytes received: %d\n", iResult); else if ( iResult == 0 ) printf("Connection closed\n"); else printf("recv failed: %d\n", WSAGetLastError()); } while( iResult > 0 ); // cleanup closesocket(ConnectSocket); WSACleanup(); return 0; } 示例代码 有关详细信息,以及 recv 函数的另一个示例,请参阅使用 Winsock 入门。

Windows Phone 8:Windows Phone 8 及更高版本上Windows Phone应用商店应用支持此函数。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。

要求     最低受支持的客户端 Windows 8.1 Windows Vista [桌面应用|UWP 应用] 最低受支持的服务器 Windows Server 2003 [桌面应用|UWP 应用] 目标平台 Windows 标头 winsock.h (包括 Winsock2.h) Library Ws2_32.lib DLL Ws2_32.dll 另请参阅

WSAAsyncSelect

WSARecv

WSARecvEx

Winsock 函数

Winsock 参考

recvfrom

select

send

socket



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3