recv函数的返回值测试

腾讯后端 C++一面:recv 返回值,什么错误是可接受的? 在 C/C++网络编程中,尤其是在处理 TCP 套接字时,recv函数扮演着基石般的角色。它是从连接对端读取传入数据的主要机制。recv 阅读详情

      在本文中, 我们来关注recv函数何时返回?  返回啥?

      我们先看服务端程序:

 

#include <stdio.h>
#include <winsock2.h> // winsock接口
#pragma comment(lib, "ws2_32.lib") // winsock实现

int main()
{
	WORD wVersionRequested;  // 双字节,winsock库的版本
	WSADATA wsaData;         // winsock库版本的相关信息
	
	wVersionRequested = MAKEWORD(1, 1); // 0x0101 即:257
	

	// 加载winsock库并确定winsock版本,系统会把数据填入wsaData中
	WSAStartup( wVersionRequested, &wsaData );
	

	// AF_INET 表示采用TCP/IP协议族
	// SOCK_STREAM 表示采用TCP协议
	// 0是通常的默认情况
	unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;

	addrSrv.sin_family = AF_INET; // TCP/IP协议族
	addrSrv.sin_addr.S_un.S_addr = inet_addr("0.0.0.0"); // socket对应的IP地址
	addrSrv.sin_port = htons(8888); // socket对应的端口

	// 将socket绑定到某个IP和端口(IP标识主机,端口标识通信进程)
	bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

	// 将socket设置为监听模式,5表示等待连接队列的最大长度
	listen(sockSrv, 5);


	// sockSrv为监听状态下的socket
	// &addrClient是缓冲区地址,保存了客户端的IP和端口等信息
	// len是包含地址信息的长度
	// 如果客户端没有启动,那么程序一直停留在该函数处
	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);
	unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);

	while(1)
	{
		getchar();
		char szRecvBuf[10000] = {0};  
        recv(sockConn, szRecvBuf, sizeof(szRecvBuf), 0);  
	}

	closesocket(sockConn);	
	closesocket(sockSrv);
	WSACleanup();
	
	return 0;
}

      启动服务端。

 

 

       再来看客户端程序:

 

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

int main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(1, 1);

	SOCKET sockClient = 0;

	// 测试recv返回值
	{
		char szRecvBuf[10] = {0};  
		int ret = recv(sockClient, szRecvBuf, sizeof(szRecvBuf), 0);  
		printf("%d, %d\n", ret, GetLastError());
	}
	
	WSAStartup( wVersionRequested, &wsaData );

	// 测试recv返回值
	{
		char szRecvBuf[10] = {0};  
		int ret = recv(sockClient, szRecvBuf, sizeof(szRecvBuf), 0);  
		printf("%d, %d\n", ret, GetLastError());
	}

	sockClient = socket(AF_INET, SOCK_STREAM, 0);

	// 测试recv返回值
	{
		char szRecvBuf[10] = {0};  
		int ret = recv(sockClient, szRecvBuf, sizeof(szRecvBuf), 0);  
		printf("%d, %d\n", ret, GetLastError());
	}

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(8888);
	connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	
	// 测试recv返回值
	{
		char szRecvBuf[10] = {0};  
		int ret = recv(sockClient, szRecvBuf, sizeof(szRecvBuf), 0);  
		printf("%d, %d\n", ret, GetLastError());
	}

	while(1)
	{
		getchar();
		char szSend[100000] = {0};
		int ret = send(sockClient, szSend, sizeof(szSend), 0);
		printf("ret is %d, error is %d\n", ret, GetLastError());
	}

	closesocket(sockClient);
	WSACleanup();

	return 0;
}

      好, 启动客户端。 我们在客户端上看到的结果是:

 

-1, 10093
-1, 10038
-1, 10057

      好, 此时关闭服务端, 客户端上的结果为:

-1, 10093
-1, 10038
-1, 10057
-1, 10054

      返回值为-1是预料之中的, 后面的错误码亦百度可查, 故不赘述。

 

      好, 我们在服务端close一下socket, 代码为:

 

#include <stdio.h>
#include <winsock2.h> // winsock接口
#pragma comment(lib, "ws2_32.lib") // winsock实现

int main()
{
	WORD wVersionRequested;  // 双字节,winsock库的版本
	WSADATA wsaData;         // winsock库版本的相关信息
	
	wVersionRequested = MAKEWORD(1, 1); // 0x0101 即:257
	

	// 加载winsock库并确定winsock版本,系统会把数据填入wsaData中
	WSAStartup( wVersionRequested, &wsaData );
	

	// AF_INET 表示采用TCP/IP协议族
	// SOCK_STREAM 表示采用TCP协议
	// 0是通常的默认情况
	unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;

	addrSrv.sin_family = AF_INET; // TCP/IP协议族
	addrSrv.sin_addr.S_un.S_addr = inet_addr("0.0.0.0"); // socket对应的IP地址
	addrSrv.sin_port = htons(8888); // socket对应的端口

	// 将socket绑定到某个IP和端口(IP标识主机,端口标识通信进程)
	bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

	// 将socket设置为监听模式,5表示等待连接队列的最大长度
	listen(sockSrv, 5);


	// sockSrv为监听状态下的socket
	// &addrClient是缓冲区地址,保存了客户端的IP和端口等信息
	// len是包含地址信息的长度
	// 如果客户端没有启动,那么程序一直停留在该函数处
	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);
	unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);

	while(1)
	{
		getchar();

		printf("close");
		closesocket(sockSrv); // add


		char szRecvBuf[10000] = {0};  
        recv(sockConn, szRecvBuf, sizeof(szRecvBuf), 0);  
	}

	closesocket(sockConn);	
	closesocket(sockSrv);
	WSACleanup();
	
	return 0;
}

      启动服务端。

 

      然后, 启动客户端, 建立tcp连接, 我们在服务端触发close操作, 发现客户端并没有变化/影响, 也就是说recv没有返回。 

 

      好, 我们继续改服务端代码:

 

#include <stdio.h>
#include <winsock2.h> // winsock接口
#pragma comment(lib, "ws2_32.lib") // winsock实现

int main()
{
	WORD wVersionRequested;  // 双字节,winsock库的版本
	WSADATA wsaData;         // winsock库版本的相关信息
	
	wVersionRequested = MAKEWORD(1, 1); // 0x0101 即:257
	

	// 加载winsock库并确定winsock版本,系统会把数据填入wsaData中
	WSAStartup( wVersionRequested, &wsaData );
	

	// AF_INET 表示采用TCP/IP协议族
	// SOCK_STREAM 表示采用TCP协议
	// 0是通常的默认情况
	unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;

	addrSrv.sin_family = AF_INET; // TCP/IP协议族
	addrSrv.sin_addr.S_un.S_addr = inet_addr("0.0.0.0"); // socket对应的IP地址
	addrSrv.sin_port = htons(8888); // socket对应的端口

	// 将socket绑定到某个IP和端口(IP标识主机,端口标识通信进程)
	bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

	// 将socket设置为监听模式,5表示等待连接队列的最大长度
	listen(sockSrv, 5);


	// sockSrv为监听状态下的socket
	// &addrClient是缓冲区地址,保存了客户端的IP和端口等信息
	// len是包含地址信息的长度
	// 如果客户端没有启动,那么程序一直停留在该函数处
	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);
	unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);

	while(1)
	{
		getchar();

		printf("close");
		closesocket(sockConn); // add


		char szRecvBuf[10000] = {0};  
        recv(sockConn, szRecvBuf, sizeof(szRecvBuf), 0);  
	}

	closesocket(sockConn);	
	closesocket(sockSrv);
	WSACleanup();
	
	return 0;
}

 

      启动服务端。

      然后, 启动客户端, 建立tcp连接, 我们在服务端触发close操作, 发现结果如下:

-1, 10093
-1, 10038
-1, 10057
0, 0

      关注一下最后的0, 0.

 

       

       之所以要扯扯recv函数返回值, 是在为后续要讨论的心跳做准备, 我们拭目以待奋斗

 

 

 

 

 

 

 

Socket 收发内部拆包封包函数 根据缓存大小批次发送和接收,内部有自己的缓冲区 阅读详情

相关推荐

ESP32+micro-ROS机器人开发实战:轻量级ROS2嵌入式集成

ROS2是现代机器人软件栈的核心框架,其基于DDS的分布式通信与QoS保障能力为多节点协同提供基础支撑;而micro-ROS作为专为微控制器优化的ROS2兼容中间件,解决了资源受限设备(如ESP32)接入ROS2生态的关键难题。其通过分层架构将DDS通信下沉至上位机Agent,使MCU仅需运行轻量Client,大幅降低内存开销(实测<180KB)并保留标准ROS2接口语义。该方案广泛应用于教育机器人、移动底盘、传感器节点等嵌入式场景,尤其适合基于ESP-IDF开发的Wi-Fi/BLE物联网机器人系统。本文以

weixin_29025501的博客 343

关于socket阻塞与非阻塞情况下的recv、send、read、write返回值.zip

关于socket阻塞与非阻塞情况下的recv、send、read、write返回值.zip

【OpenClaw从入门到精通】第11篇:OpenClaw 2026多模态实战全攻略:OCR/语音/图像自动化(附完整代码+双部署方案)

本文聚焦OpenClaw 2026版核心升级的多模态能力,从底层架构原理到实操落地全流程拆解。先解析“统一指令解析+多工具适配器”的核心设计逻辑,再提供阿里云规模化部署(适合批量任务)与本地汉化版部署(适合隐私数据调试)的详细步骤,含依赖安装、配置验证完整操作;随后落地三大高频实战场景——OCR合同信息结构化提取、会议录音自动转写纪要、电商商品图片智能打标,每个场景均提供可直接运行的完整代码、执行结果演示及流程说明;最后补充多模态任务避坑指南、性能优化技巧与成本控制方案。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2550

C++编程socket编程用recv函数接收,返回值为0解决方案

        先讲下背景,我需要写一个客户端,用winsock发送请求到服务器,服务器用tomcat写的,通过responseBody返回字符串作为发还给客户端的数据。 错误表现为:         在用Visual Studio2017调试的时候,在Debug模式下,是没有任何问题的,而在Release模式下,则报错。         错误代码如下: char buffer[...

code_while的博客 2万+

recv函数返回值说明

<br />recv函数返回值说明<br />TechDocs 2010-05-29 16:06:21 阅读108 评论0字号:大中小<br />recv函数<br /><br />int recv( SOCKET s, char FAR *buf, int len, int flags);<br />不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;<br />第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;<br />

8039

socket:10038错误

winSock的一个bug:当closesocket多次错误使用时会导致问题        这几天想在一个开源的代码上进行修改,以期研发出一个产品出来。        程序原来是单线程网络程序,需要修改为多线程,修改之后,总是出问题,辅助线程中的recv函数总是运行一阵子之后收到长度为-1的数据报,导致程序运行不正确甚至崩溃。         由于是多线程,只好打日志进行调试,发

对牛乱弹琴 2万+

WinSocket套接字关于Connect函数通过GetLastError 返回10038或者(在一个非套接字上尝试了一个操作)

今天在调试代码的时候,突然发现原先的Connect函数居然不能连接,并且通过GetLastError函数获取值的时候,返回的是10038,经过一番折腾和上网查资料,终于把问题解决了,现在把我解决的经验跟大家分享,与大家共同分享。 1、首先通过GetLastError获取的返回值值为10038,然后通过查找MSDN发现返回10038说明的原因是:"在一个非套接字上尝试了一个操作" 2、通

hyy829119的专栏 6190

Linux网络编程:recv返回值

recv是网络编程中用于TCP传输接收数据的接口,由于工作中一直没有接触到网络编程,虽然知道这个函数,但是没有使用经验,所有对接口细节不是很了解。 直到前阵子在项目中调试第三方的源码时,跟踪到这个函数,才发现它的返回值和我想象的不太一样。 recv函数的原型: ssize_t recv(int sockfd, void* buf, size_t len, int flags); 之前知道的是如果读取成功,会返回实际读取到的字节数,但是如果读取不到数据呢?一直想当然的认为会返回0,其实并不是,当读取不到数据

m0_67401499的博客 1753

c语言recv函数返回值,谈谈recv()函数返回值

网上某论坛有这样一个问题:当recv()函数返回值为0时,能不能在接收端不关闭套接字,以便这条建立好的C/S通信下次可以直接使用?我对这个问题的回答是:不能。原因是:此时即使接收端不关闭套接字,发送端也已经关闭相应的套接字,这条连接需要从accept()/connect()两个函数这里重新建立。测试代码如下:#include "stdafx.h"#include #include #pragma...

weixin_39928993的博客 1511

关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

1、阻塞模式与非阻塞模式下recv返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 0接收到数据大小,特别:返回值 2、阻塞模式与非阻塞模式下write的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞write返回值没有区分,都是 0发送数据大小,特别:返回值 3、阻塞模式下read返回值 非阻塞模式下read返回值 0表示接收到数据。 这

2687

非阻塞模式下 SEND 和 RECV 函数返回值总结

send和recv函数的各种返回值意义: 返回值 n 返回值含义 大于 0 成功发送 n 个字节 0 对端关闭连接 小于 0( -1) 出错或者被信号中断或者对端 TCP 窗口太小数据发不出去(send)或者当前网卡缓冲区已无数据可收(recv) 我们来逐一介绍下这三种情况: 返回值大于 0 对于send和recv函数返回值大于0,表示发送或接收多少字节,需要注意的是,在这种情形下,我们一定要判断下 send 函数返回值是不是我们期望发...

zhjixi495的专栏 6327

lwip recvfrom函数 非阻塞_非阻塞模式下 send 和 recv 函数返回值

我们来根据前面的讨论来总结一下send和recv函数的各种返回值意义:返回值 n返回值含义大于 0成功发送 n 个字节0对端关闭连接小于 0( -1)出错或者被信号中断或者对端 TCP 窗口太小数据发不出去(send)或者当前网卡缓冲区已无数据可收(recv)我们来逐一介绍下这三种情况:返回值大于 0对于send和recv函数返回值大于0,表示发送或接收多少字节,需要注...

weixin_42116672的博客 4515

send()函数recv()函数详解

目录 1.send()函数 2. recv()函数 1.send()函数 函数原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags); 功能:向套接字中发送数据 参数:sockfd:向套接字中发送数据 buf:要发送的数据的首地址 ...

MrWangHao的博客 6917

recv函数linux,linux 下调用recv函数,死循环在recv函数里面,什么原因?

linux 下调用recv函数,死循环在recv函数里面,什么原因?linux服务器,在连接只有1000个时候,一切正常,到连接到2000以上的时候,就死循环在recv函数里面,cpu占用率很高,因为recv是系统函数,也不知道他在里面干什么。程序是epoll实现的。 有谁碰到过类似问题么?或者是能指导一个努力的方向? 回1楼:不是建立连接的时候死循环,而是跑了一段时间后,在调用recv函数的时候...

weixin_39927508的博客 659

recv函数返回值处理(包括errno的处理)

1、recev()函数返回值: >0:接收到的数据大小; =0:连接关闭; <0:出错。 在出错的情况下, 这三种错误下认为连接是正常的,继续接收 if(errno == EINTR ||(errno == EAGAIN)||errno == EWOULDBLOCK) continue; if(FD_ISSET(connfd,......

modi000的博客 9717

socket error 10038查错

最近在做一个设备监控软件,是在另外一个软件的基础上修改的, 主要用到socket进行发送和接收。但是在接收的的过程中recv()的返回出错,GetLastError()得到10038, 错误码描述为Socket operation on non-socket。意思是socket不对。但是代码中的整个接收过程并没有对socket进行改动。这个问题令我头疼不已。 经过大半天的调...

WO125654193的博客 1954

recv()函数返回值说明,用返回值确定不同的情况

recv()函数是网络编程中常用的一个函数,特别是在使用 TCP 套接字时。它用于从连接的套接字接收数据。

icon_sunshine的博客 1095

基于C#利用interface实现上位机与fanuc机器人的通信,亲测可用

自己写的,亲测可用,软件、说明书也都有,博客里还有详细的步骤说明,希望能帮助到大家

上一篇: 判断是否为递增数组(某同事最近去某公司遇到的笔试题)
下一篇: 郭靖和黄蓉竟然是这样死的!---某些人最近看了柴静的《穹顶之下》后狂喷她,这些人可能就是本文中的甲乙丙丁
涛歌依旧
涛歌依旧 优质创作者: 后端开发技术领域 优质创作者: 后端开发技术领域 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄14年 28万+粉丝 2592原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值