recv用TCP和TUDP下的区别
recv是可以用在UDP套接字上的,前提是该套接字调用过bind或者connect,那它用在TCP和UDP套接字上时有什么区别呢?
下面做一个测试,分别使用UDP、TCP实现一对C/S、客户端发送12字节数据,服务器接受的时候用10字节大小的buffer去接受。
TCP
tcpSvr:
/*
* 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, , );
printf("recv data len [%d]\n", iRet);
printf("recv content [%s]\n", buf);
sleep();
}
close(fd); return ;
}
tcpCli:
#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_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;
} char buf[] = "hello world!";
while ()
{
int iRet = send(fd, buf, strlen(buf), );
printf("Send data len [%d]\n", iRet);
printf("Send content [%s]\n", buf);
sleep();
}
close(fd); return ;
}
结果:


UDP
udpSvr
#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;
} char buf[];
while()
{
memset(buf, , );
int iRet = recv(fd, buf, , );
printf("recv data len [%d]\n", iRet);
printf("recv content [%s]\n", buf);
}
close(fd); return ;
}
udpCli:
#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); char buf[] = "hello world!";
while ()
{
int iRet = sendto(fd, buf, strlen(buf), , (struct sockaddr*)&addr, sizeof(addr));
printf("Send data len [%d]\n", iRet);
printf("Send content [%s]\n", buf);
break;
}
close(fd); return ;
}
结果:


结论:
当收到的数据大于传入recv的buffer大小时,多余的字节,UDP会丢弃,TCP可以在下次调用recv的时候读取到,这也是为什么说TCP是基于流的协议。
所以当读取UDP数据时一定要注意buffer的大小,应使它大于IP层的数据报大小。
还需要注意的是,发送UDP数据的时候包的大小不应该导致IP分片,否则会造成乱序、丢包。
recv用TCP和TUDP下的区别的更多相关文章
- OSI及TCP/IP的概念和区别
什么是TCP/IP协议 TCP/IP协议(Transfer Controln Protocol/Internet Protocol)叫做传输控制/网际协议,又叫网络通讯协议,这个协议是Internet ...
- 从Docker在Linux和Windows下的区别简单理解Docker的层次结构
上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...
- TCP协议与HTTP协议区别
一.TCP协议与HTTP协议区别 1.直观认识 TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页 ...
- 盒模型与在低版本IE下的区别
对css有一定了解的同学一定听说过盒模型,在这里以我自己的一点儿了解和认知来解释一下盒模型与盒模型在低版本IE浏览器下与其他浏览器下的区别. W3c标准下的盒模型 盒模型由 content(内容),p ...
- TCP/IP协议原理与应用笔记05:TCP/IP协议下的网关
大家都知道,从一个房间走到另一个房间,必然要经过一扇门.同样,从一个网络向另一个网络发送信息,也必须经过一道“关口”,这道关口就是网关.顾名思义,网关(Gateway)就是一个网络连接到另一个网络的& ...
- socket在windows下和linux下的区别
原文:socket在windows下和linux下的区别 1)头文件 windows下winsock.h/winsock2.h linux下sys/socket.h 错误处理:errno.h 2 ...
- 第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难
第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难 如何做个靠谱的人? 有问有答,任务发送和接收有记录,完成有反馈. 如何实现一个靠谱的协议? TCP 协议使用的也是同样的模式.为了保证顺 ...
- linux下recv 、send阻塞、非阻塞区别和用法
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模式 ...
- TCP和UDP的具体区别
TCP和UDP的最完整的区别 TCP UDP TCP与UDP基本区别: 1.基于连接与无连接 2.TCP要求系统资源较多,UDP较少: 3.UDP程序结构较简单 4.流模式(TCP)与数据报模式(UD ...
随机推荐
- fileUpload(草稿)
Java关于文件上传的一个例子 发表于2012/6/7 13:01:56 1374人阅读 分类: JavaWeb 文件上传不能用get方式提交,因为他提交的数据量最多只有1kb, IE浏览器默认情况 ...
- sid-msg.map文件概述
我这边编写了magic对应的指定文件规则,但是运行的时候发现储存的文件中包含我未指定的数据文件: 在rules下边看的时候,发现有sid-msg.map文件,上网了解下这个文件是干啥的.. 下边文章来 ...
- 重写Checkbox 改写选择框的大小
/* 作者:Starts_2000 * 日期:2009-07-30 * 网站:http://www.csharpwin.com CS 程序员之窗. * 你可以免费使用或修改以下代码,但请保留版权信息. ...
- android 当ListView滚动时自动调用 onCheckedChanged 导致CheckBox 状态不停变化 的解决办法
今天在做一个含有CheckBox 的ListView时,发现当初始化CheckBox的状态后, 滚动ListView,其中CheckBox 的选中状态不停的发生变化.最后发现原因是 ListView滚 ...
- C语言中 不定义结构体变量求成员大小
所谓的求成员大小, 是求成员在该结构体中 用 sizeof(结构体名.结构体成员名) 求来的. 很多时候我们需要知道一个结构体成员中的某个成员的大小, 但是我们又不需要定义该结构体类型的变量(定义的话 ...
- cygwin ctrl+s的问题
使用cygwin的时候,因为习惯了ctrl+s保存文档,使用vim时也顺手按下去了,然后cygwin就冻结了. 这个时候可以按下 ctrl+q 来重新激活 cygwin
- 还没被玩坏的robobrowser(2)——安装及快速开始
安装robobrowser 注意:这里假设你知道如何使用pip安装python的库的知识,如果你不了解这一块的话,点这里获取帮助. 强烈推荐使用pip安装. pip install robobrows ...
- java对象内存占用
一.前言想知道java对象在内存中的占用情况吗?感谢这位大神的无私分享. http://yueyemaitian.iteye.com/blog/2033046 二.原文的扩充1. 增加了代理jar包的 ...
- 【转载】Ajax JS 跨域请求
原文: 简单的ajax请求:http://blog.csdn.net/net_lover/article/details/5172509 复杂的ajax请求:http://blog.csdn.net/ ...
- 转 Java笔记:Java内存模型
Java笔记:Java内存模型 2014.04.09 | Comments 1. 基本概念 <深入理解Java内存模型>详细讲解了java的内存模型,这里对其中的一些基本概念做个简单的笔记 ...