c语言recv函数返回值,谈谈recv()函数的返回值
网上某论坛有这样一个问题:当recv()函数的返回值为0时,能不能在接收端不关闭套接字,以便这条建立好的C/S通信下次可以直接使用?
我对这个问题的回答是:不能。
原因是:此时即使接收端不关闭套接字,发送端也已经关闭相应的套接字,这条连接需要从accept()/connect()两个函数这里重新建立。
测试代码如下:
#include "stdafx.h"
#include
#include
#pragma comment(lib,"ws2_32")
const int m_listen_port=9923;
#define buff_size 1024
int main(int argc, char* argv[])
{
int ret_common=0;
int ret_error=0;
WSAData wsadata;
WORD m_version;
m_version=MAKEWORD(2,2);
WSAStartup(m_version,&wsadata);
SOCKET
m_server_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (m_server_sock==INVALID_SOCKET)
{
ret_error=WSAGetLastError();
printf("error for
socket() and caputre error code: %d\n",ret_error);
return 0;
}
SOCKADDR_IN m_sock_addr;
memset(&m_sock_addr,0,sizeof(m_sock_addr));
m_sock_addr.sin_family=AF_INET;
m_sock_addr.sin_addr.S_un.S_addr=INADDR_ANY;
m_sock_addr.sin_port=htons(m_listen_port);
ret_common=bind(m_server_sock,(SOCKADDR*)&m_sock_addr,sizeof(m_sock_addr));
if (ret_common==SOCKET_ERROR)
{
ret_error=WSAGetLastError();
printf("error for
bind() and caputre error code: %d\n",ret_error);
return 0;
}
listen(m_server_sock,SOMAXCONN);
fd_set fd_socket;
FD_ZERO(&fd_socket);
FD_SET(m_server_sock,&fd_socket);
while (1)
{
fd_set
fd_read=fd_socket;
ret_common=select(0,&fd_read,NULL,NULL,NULL);
if
(ret_common>0)
{
for
(unsigned int i=0;i
{
BOOL
m_boolen_ret=FD_ISSET(fd_socket.fd_array[i],&fd_read);
if
(m_boolen_ret)
{
if
(fd_socket.fd_array[i]==m_server_sock)
{
SOCKADDR_IN
m_client_addr;
memset(&m_client_addr,0,sizeof(m_client_addr));
int
m_client_addr_len=sizeof(m_client_addr);
SOCKET
m_client_sock=accept(m_server_sock,(SOCKADDR*)&m_client_addr,&m_client_addr_len);
printf("accpet
a connection from socket %d\n",m_client_sock);
FD_SET(m_client_sock,&fd_socket);
}
else
{
char
m_recv_buff[buff_size];
memset(m_recv_buff,0,buff_size);
ret_common=recv(fd_socket.fd_array[i],m_recv_buff,sizeof(m_recv_buff),0);
if
(ret_common>0)// 接收数据包正常,数据包中的数据大于0个字节;
{
printf("receive
data \"%s\" from socket
%d\n",m_recv_buff,fd_socket.fd_array[i]);
continue;
}
else
if
(ret_common==0)// 传输数据包操作完成,连接断开(gracefully);
{
ret_error=WSAGetLastError();
printf("there
is a connection is gracefully closed and capture error code:
%d,socket:%d\n",
ret_error,fd_socket.fd_array[i]);
closesocket(fd_socket.fd_array[i]);
FD_CLR(fd_socket.fd_array[i],&fd_socket); continue;
}
else//
传输数据包出错;
{
ret_error=WSAGetLastError();
closesocket(fd_socket.fd_array[i]);
FD_CLR(fd_socket.fd_array[i],&fd_socket);
if
(ret_error==10054)// 连接被强制断开;
{
printf("client
closed the connection by force, test ret_common:
%d,socket:%d\n",
ret_error,ret_common,fd_socket.fd_array[i]);
}
else//
输出其它错误;
{
printf("error
for recv(), capture error code: %d, test ret_common:
%d,socket:%d\n",
ret_error,ret_common,fd_socket.fd_array[i]);
} continue;
}
}
}
} }
else
{
ret_error=WSAGetLastError();
printf("error
for select() and capture error code: %d\n",ret_error);
break;
}
}
closesocket(m_server_sock);
WSACleanup();
return 0;
}
这段发送端代码不是我写的,看起来可能比较乱,请见谅:
for (int i=0;i<10;i++)
{
strncpy(m_send_buff,"data",sizeof("data"));
char a[20];
memset(a,0,20);
itoa(i+1,a,10);
strncat(m_send_buff,a,20);
ret_common=send(s,m_send_buff,sizeof(m_send_buff),0);
if
(ret_common==SOCKET_ERROR)
{
ret_error=WSAGetLastError();
printf("error
for send() and capture error code: %d\n",ret_error);
break;
}
else
{
printf("send
data: %s\n",m_send_buff);
}
Sleep(1000);
}
Sleep(6000);
// 关闭套节字
::closesocket(s);
Sleep(10000);
printf("ret\n");
return 0;
当包含这段代码的程序发送数据包到包含上一段代码的程序时,发送数据完毕,在等6秒钟后发送数据的套接字才关闭,而接收端也是等6秒钟才输出客户端关闭(gracefully)关闭的信息,再等10描述,发送数据的程序才推出。
总结一下:
(1)当接收端被强行关闭时,ret_common为-1,WSAGetLastError()返回值(即ret_error)为10054(0x2746);
(2)当数据传输执行closesocket()(closesocket()参数为发送数据的套接字)之后,接收端的返回值(即ret_common)为0。
(3)在传输过程中,如果接收端被强行关闭,那么发送端的send()函数的返回值(即ret_common)为-1,WSAGetLastError()的返回值(即ret_error)为10054(0x2746)。
需要注意一点:
WSAGetLastError()的返回值:10054,与GetLastError()的返回值:0x2746,这两个错误返回值是相等的(不同的是针对WSAGetLastError()函数和GetLastError()函数的返回值类型不同(WSAGetLastError()返回int类型操作数;GetLastError()返回DWORD类型操作数))。
c语言recv函数返回值,谈谈recv()函数的返回值相关推荐
- mysql linux 函数返回值_linux recv函数返回值分析
函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags); 该函数第一个参数制定接收端套接字描述符; 第二个参数指明一个缓冲区, ...
- C语言基础入门48篇_20_函数入门:为什么使用函数?(函数使得程序模块化 使用函数封装细节,使得程序员只要面向函数的接口编程(参数与返回值),而不用关心函数内部细节)
菜鸟和高手都会基本,那菜鸟为什么是菜鸟,高手为什么是高手呢?很大的区别在于,高手写的程序[结构性]更好,更容易维护.而函数就是C语言结构化的一种手段. 函数可以将大的计算任务划分为多个较小的任务(解耦 ...
- smali语言详解之一般/构造方法(函数)的声明与返回值关键字
smali语言详解之一般/构造方法(函数)的声明与返回值关键字 一. smali语言的方法声明格式 .method与.end method成对出现,类似于java中的花括号 1.1.非静态的一般方法 ...
- c语言函数返回值类型必须,C++中函数类型与定义的函数返回值类型必须相同么?...
C++中函数类型与定义的函数返回值类型必须相同么?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C++中函数类型与定义 ...
- c语言调用oracle函数返回值吗,C语言通过值和引用函数
. 将参数值或数据传递给C语言函数有两种方法:通过值调用和通过引用调用.原始值在通过值调用时不修改,但通过引用调用时,在函数中可进行修改. 下面将分别讲解如何通过值调用和通过引用调用,并用使用示例逐个 ...
- c语言字符串作为函数返回值的类型,返回字符串类型的函数怎么写?
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 描述 请判断一个数是不是水仙花数. 其中水仙花数定义各个位数立方和等于它本身的三位数. 输入 有多组测试数据,每组测试数据以包含一个整数n(100< ...
- Go 学习笔记(61)— Go 高阶函数、函数作为一等公民(函数作为输入参数、返回值、变量)的写法
函数在 Go 语言中属于"一等公民(First-Class Citizen)"拥有"一等公民"待遇的语法元素可以如下使用 可以存储在变量中: 可以作为参数传递给 ...
- Python 函数参数有冒号 声明后有- 箭头 返回值注释 参数类型注释
在python3.7 环境下 函数声明时能在参数后加冒号,如图: 1 def f(ham: str, eggs: str = 'eggs') -> str : 2 print("Ann ...
- php 函数返回值mixed,认识函数的类型、参数与返回值
函数的类型.参数与返回值 一.函数的基本语法语法 functionfunctionName(类型限定参数列表):返回值类型 { } 案例:计算两个数之和. functionsum(int$a,int$ ...
最新文章
- Spring入门简介
- Godaddy如何导入导出MSSQL数据库
- 在Windows2012R2中如何安装IIS8.5
- 几百个Android开源个性化控件、工具库、项目、开发工具快快收藏
- docker知识总结
- Linux系统通过FTP进行文档基本操作【华为云分享】
- python进程间通信总结_进程间通信方式总结(优缺点)
- 【Zookeeper学习】Apache Zookeeper项目简介
- STP-2-三个选择
- sql替换字符串中的部分字符
- 手机三十分钟熄屏如何一直亮_如何让手机屏幕常亮
- 【分享】测试小白如何测试手机整机系统测试
- HDU - 5977 Garden of Eden (树形dp+容斥)
- 2016年上半年系统集成中项4月6日作业
- 湖北经济学院法商学院计算机分数线,湖北经济学院法商学院2018年各省及各专业录取分数线及最低录投档线【理科 文科】...
- MapServer 7.0.3 Documentation 翻译
- 北京哪里可以买到含羞草啊?或者种子也行
- 大型电商网站:第一章:主要电商模式
- Liferay中的workflow
- mysql实现统计查询_MySQL 统计查询实现代码
热门文章
- httos双向认证配置_HTTPS双向验证,如何设置
- VTK修炼之道52:图形基本操作进阶_多分辨率策略(模型抽取的三种方法)
- Uncaught TypeError: Object #Document has no method 'load'
- 注入工具的原理和开发
- 传智C++课程笔记-1
- 基于STM32,无人船岸基信息处理代码--python实现
- 如何通过JavaScript动态加载js
- jsp里面声明了utf-8格式,也写了字符编码过滤器,数据库编码也是utf-8,就连java.......
- 第15章习题解答(二)——《x86汇编语言:从实模式到保护模式》读书笔记41
- 【unix时间戳小示例】linux/unix系统获取unix时间戳