tcp/udp只发不接,会丢包还是send失败?
这篇文章源于我看libevent的源码时想到的问题,对于libevent的buffer机制,如果接受端一直不取数据的话,会怎样?如果丢包,不现实,因为会导致数据丢失,如果不丢包,就会导致占用内存一直扩大。
由此我想到对于tcp/udp如果一直发,接收端不调用recv取数据会怎样,是会导致send失败,还是多余的数据丢弃?想再多还不如写个代码试一试,下面看代码。
tcp:client端一直发,sever端接受连接后不调用recv
客户端
/*
* gcc -o tcpCli ./tcpCli.c
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <errno.h> const int PORT = ; int main(int argc, char **argv)
{
int fd = socket(AF_INET, SOCK_STREAM, );
if (fd == -)
{
perror("socket");
return errno;
} struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(PORT); if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -)
{
perror("connect");
return errno;
} fcntl(fd, F_SETFL, O_NONBLOCK); char buf[] = "hello world!";
while ()
{
int iRet = send(fd, buf, , );
if (iRet == -)
{
perror("send");
}
else
{
printf("Send data len [%d]\n", iRet);
printf("Send content [%s]\n", buf);
}
sleep();
}
close(fd); return ;
}
服务端
/*
* gcc -o tcpSvr ./tcpSvr.c
*/
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <errno.h> const int PORT = ; int main(int argc, char **argv)
{
int fd = socket(AF_INET, SOCK_STREAM, );
if (fd == -)
{
perror("socket");
return errno;
} struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT); if (- == bind(fd, (struct sockaddr*)&addr, sizeof(addr)))
{
perror("bind");
return errno;
} if (- == listen(fd, ))
{
perror("listen");
return errno;
} struct sockaddr_in cli_addr;
socklen_t len = sizeof(cli_addr);
int client = accept(fd, (struct sockaddr*)&cli_addr, &len);
if (client == -)
{
perror("accept");
return errno;
} printf("accept an client\n"); char buf[];
while()
{
memset(buf, , );
//int iRet = recv(client, buf, 10, 0);
int iRet = ;
printf("recv data len [%d]\n", iRet);
printf("recv content [%s]\n", buf);
sleep();
}
close(fd); return ;
}
结果:
很明显,会导致send发送失败,所以需要注意的是,用send发送数据如果tcp缓冲区空间不足时,只会发送部分数据,这时就需要程序员自己来记录发送位置,等到缓冲区可发送时再继续发送。
但是获取到的写缓冲区大小和发送的数据大小不一致,不知道是什么原因,这个待后面继续研究。
udp:client端一直发,一段时间后关闭,sever端等待客户端关闭,再开始接受
客户端
/*
* gcc -o udpCli ./udpCli.c
*/
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <errno.h> const int PORT = ; int main(int argc, char **argv)
{
int fd = socket(AF_INET, SOCK_DGRAM, );
if (fd == -)
{
perror("socket");
return errno;
} struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(PORT); // get send buffer size
int iWBufSize;
socklen_t optLen = sizeof(iWBufSize);
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &iWBufSize, &optLen);
printf("Write buffer size = %d\n", iWBufSize); int iRBufSize;
optLen = sizeof(iRBufSize);
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &iRBufSize, &optLen);
printf("Read buffer size = %d\n", iRBufSize); char buf[] = "hello world!";
int iCount = ;
while ()
{
sprintf(buf, "%d", iCount);
int iRet = sendto(fd, buf, , , (struct sockaddr*)&addr, sizeof(addr));
if (iRet == -)
{
perror("sendto");
break;
}
else
{
// printf("Send data len [%d]\n", iRet);
iCount++;
}
if (iCount % == )
{
printf("Send package count %d\n", iCount);
sleep();
}
}
printf("Send package count %d\n", iCount);
close(fd); return ;
}
服务端
/*
* gcc -o udpSvr ./udpSvr.c
*/
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <errno.h> const int PORT = ; int main(int argc, char **argv)
{
int fd = socket(AF_INET, SOCK_DGRAM, );
if (fd == -)
{
perror("socket");
return errno;
} struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT); if (- == bind(fd, (struct sockaddr*)&addr, sizeof(addr)))
{
perror("bind");
return errno;
} getchar(); char buf[];
int iCount = ;
while()
{
memset(buf, , );
int iRet = recv(fd, buf, , );
iCount++;
// printf("recv data len [%d]\n", iRet);
printf("Recv package count[%d]\t", iCount);
printf("recv content [%s]\n", buf);
}
close(fd); return ;
}
结果:
可以看到,客户端一共发送1300个包,而服务端仅仅能收到前面69个包,后面的全被丢弃了。
根据收到的包的个数和每个包的大小,计算出换冲区的大小:103500,不知道这个值算的对不对。
tcp/udp只发不接,会丢包还是send失败?的更多相关文章
- UDP主要丢包原因及具体问题分析
UDP主要丢包原因及具体问题分析 一.主要丢包原因 1.接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来 ...
- TCP/UDP详解
转载:http://www.cnblogs.com/visily/archive/2013/03/15/2961190.html, 作者:望梅止渴 相关: HTTP协议详解 深入理解HTTP协议 T ...
- 针对UDP丢包问题,进行系统层面和程序层面调优
转自:https://blog.csdn.net/xingzheouc/article/details/49946191 1. UDP概念 用户数据报协议(英语:User Datagram Proto ...
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
使用TCP协议连续传输大量数据时,是否会丢包,应如何避免? 比如发送文件.记得有人提过可能会发生什么堆栈溢出.怎样避免呢?是不是可以收到数据后发送确认包,收到确认包后再继续发送.或是发送方发送了一些数 ...
- 收集TCP端口的访问延迟和丢包率
需求: 找一款工具可以对TCP 80端口 收集 访问延迟和丢包率 找到的工具: 1.Hping : http://www.hping.org/ 2.paping : https://docs.azu ...
- 1、如何抓取Modbus TCP/UDP 数据包实战
CEIWEI最近发布了Modbus RTU Over TCP/UDP 过滤监控的新工具,下面以Modbus RTU TCP为示例,讲解如何抓取Modbus通信数据包,因为CEIWEI ModbusMo ...
- MTU-TCP/IP协议栈-linux kernel-TCP丢包重传-UDP高性能-AI- ip数据报 tcp数据报
1.IP协议首部 TCP报文段的首部 UDP分组结构 ip数据报 tcp数据报 UDP校验 w 报文长度该字段指定UDP报头和数据总共占用的长度.可能的最小长度是8字节,因为UDP报头已经占用了 ...
- tcp粘包,udp丢包
TCP是面向流的, 流, 要说明就像河水一样, 只要有水, 就会一直流向低处, 不会间断. TCP为了提高传输效率, 发送数据的时候, 并不是直接发送数据到网路, 而是先暂存到系统缓冲, 超过时间或者 ...
- day34 基于TCP和UDP的套接字方法 粘包问题 丢包问题
TCP 基于流的协议 又叫可靠性传输协议 通过三次握手 四次挥手 来保证数据传输完毕 缺点效率低 正因为是基于流的协议 所以会出现粘包问题粘包问题:原因一:是应为数据是先发送给操作系统,在操作系统中有 ...
随机推荐
- 使用Java调用JS
import junit.framework.TestCase; import javax.script.ScriptEngine; import javax.script.ScriptEngineM ...
- java 结束程序进程 代码
结束firefox的进程,一句代码就够了,如下: Runtime.getRuntime().exec("taskkill /F /IM firefox.exe"); 结束qq: R ...
- Linux信号机制
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- Android Developers:支持不同的屏幕密度
这节课程向你展示如何通过提供不同的资源和使用与分辨率无关的测量单位,支持不同屏幕密度. 使用密度无关的像素 —————————————————————————————————————————————— ...
- [转]JVM参数设置、分析
不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM.GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java ...
- MySQL通过Explain查看select语句的执行计划结果触发写操作
[背景] 某某同学执行了一下Explain结果结果发现数据库有了一条写入操作,恭喜这位同学你的锅到货了,你签收一下: 对! 你没有听错,在一种场景下就算是Explain也会引发数据的写操作,就这是外层 ...
- 基于数据库构建分布式的ID生成方案
在分布式系统中,生成全局唯一ID,有很多种方案,但是在这多种方案中,每种方案都有有缺点,下面我们之针对通过常用数据库来生成分布式ID的方案,其它方法会在其它文中讨论: 1,RDBMS生成ID: 这里我 ...
- Hadoop hostname: Unknown host
本来下想在一台虚拟机上,搭建一个hadoop的测试hadoop,用于调试和阅读hadoop源代码,发现在虚拟机上执行: $hostname -i hostname: Unknown host 这个是因 ...
- [LeetCode] Meeting Rooms I & II
Meeting Rooms Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s ...
- Android build.gradle
apply plugin: 'com.android.application' android { /*编译版本 , 因此我们强烈推荐总是使用最新的 SDK 进行编译 targetSdkVersion ...