socket编程中套接字缓冲区大小的问题

HW_Coder0501 2017-06-29 05:05:22
一直对socket编程中的套接字缓冲区的大小等有关知识感觉很模糊,今天在网上看到这么一段话:
如果套接字sockfd的发送缓冲区中没有数据或者数据被协议成功发送完毕后,recv先检查套接字sockfd的接收缓冲区,如果sockfd的接收缓冲区中没有数据或者协议正在接收数据,那么recv就一起等待,直到把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲区中的数据copy到buff中(注意协议接收到的数据可能大于buff的长度,所以在这种情况下要调用几次recv函数才能把sockfd的接收缓冲区中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的)”

recv函数:ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);

这段话中提到协议接收到的数据如果大于buff的长度,就需要调用多次recv才能把接收缓冲区的数据copy完,但如果我们要recv的数据长度nbytes大于缓冲区的长度(也就是协议接收到的数据)时,那么recv又该怎么做?
...全文
1439 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
LubinLew 2017-07-05
  • 打赏
  • 举报
回复
那里是用来做sinffer(嗅探工具)的, 拿到的是原始包,除非你想自己在写一套协议栈处理数据.
HW_Coder0501 2017-07-05
  • 打赏
  • 举报
回复
引用 21 楼 lgbxyz 的回复:
速度不会下降,只会比读文件快。 不用mmap,也用不到 memcpy。
再请教您一个问题,我今天看到一篇文章,上面讲socket也可以使用mmap,但讲的好像是基于UDP协议的数据包,不知道基于TCP的字节流可不可以用这种方式实现? http://blog.csdn.net/ruixj/article/details/4153118
LubinLew 2017-07-05
  • 打赏
  • 举报
回复
sniffer 只是把正常协议栈中数据copy一份用来分析.
HW_Coder0501 2017-07-05
  • 打赏
  • 举报
回复
引用 24 楼 lgbxyz 的回复:
那里是用来做sinffer(嗅探工具)的, 拿到的是原始包,除非你想自己在写一套协议栈处理数据.
那这种方式可以用来传输传输字节流数据吗?如果可以需要对原始包在应用层做什么处理?
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 9 楼 lgbxyz 的回复:
自然是内核buff空了,recv声明的buff只能填充不能清空啊
内核buff空了会返回,如果读到nbytes字节的数据,而内核buff还没有空,这时也会返回的吧?
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
自然是内核buff空了,recv声明的buff只能填充不能清空啊
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 7 楼 lgbxyz 的回复:
buff空了就返回了,不会读满nbytees,tcp的send/recv 等价于 read/write。 你都做了各种尝试了,试一下不就明确了吗
试了一下一次recv 500M好像会出现错误。 还有,你这里的buff 是指recv的第二参数,还是内核缓冲区?
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
buff空了就返回了,不会读满nbytees,tcp的send/recv 等价于 read/write。 你都做了各种尝试了,试一下不就明确了吗
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
是的,但如果recv的第三个参数nbytes远远大于接收缓冲区的长度,这时recv是读满一个缓冲区长度的数据就返回吗?还是阻塞在那里一定要读到nbytes长度的数据才返回?(假定第四个参数为0)[/quote] 有多少读多少,读到的字节数就是其返回值[/quote] 我们在write或recv时都是用的循环的方式,我试了一下write 500M的数据一次循环就可成功,如果是recv的话,一次可以recv多少呢?
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 21 楼 lgbxyz 的回复:
速度不会下降,只会比读文件快。 不用mmap,也用不到 memcpy。
我这个比较特殊,必须要用到mmap,之后再将被mmap内存中的数据write到sockfd中。这中间没有用到memcpy。
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
速度不会下降,只会比读文件快。 不用mmap,也用不到 memcpy。
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 19 楼 lgbxyz 的回复:
没看明白, 你到底是要上传还是下载? 可以把要发送的文件mmap到内存,会提升,但是对点对点通信而言不会明显。 除非你的程序有重大bug,否则简单的TCP通信不会性能慢的问题,你还是先确认一下带宽吧。
我是在下位机先mmap,之后将被mmap地址的数据write到sockfd传到上位机(server),中间没有使用memcpy这一api,这样速度会降低吗?
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
没看明白, 你到底是要上传还是下载? 可以把要发送的文件mmap到内存,会提升,但是对点对点通信而言不会明显。 除非你的程序有重大bug,否则简单的TCP通信不会性能慢的问题,你还是先确认一下带宽吧。
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 17 楼 lgbxyz 的回复:
如果你的程序没有问题, 只能通过多线程/进程 解决。 通常是先通信获取需要下载文件的大小, 然后起多线程 每个下载 其中一部分。
在我的下位机程序(client)中,我用了一次mmap,之后没有用memcpy拷贝内存,而是直接用write将mmap之后的数据写入到sockfd中,不知道 时间是不是浪费在了这里?直接write和memcpy之后再write进sockfd哪个更快点?
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
如果你的程序没有问题, 只能通过多线程/进程 解决。 通常是先通信获取需要下载文件的大小, 然后起多线程 每个下载 其中一部分。
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 15 楼 lgbxyz 的回复:
首先你得先确定一下 server 和 client 之间的速率, 比如server上搭建一个http server,使用http下载需要多少时间, 通常来说你的实现应该小于http下载的时间。 光增大buff对高并发会有明显提示,你只是单个实例自然看不出提升。 如果速率慢 可以考虑多线程下载。
那单对单的连接传输速度应该怎么提升?我的server和client都是自己写的程序,基于TCP传输,而且也应该用不到多线程。
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
首先你得先确定一下 server 和 client 之间的速率, 比如server上搭建一个http server,使用http下载需要多少时间, 通常来说你的实现应该小于http下载的时间。 光增大buff对高并发会有明显提示,你只是单个实例自然看不出提升。 如果速率慢 可以考虑多线程下载。
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 13 楼 lgbxyz 的回复:
这个你得具体需求具体分析,增大buff(内核或者传入buff)都是 空间换时间。 多路复用也能提高并发性能。
我是点对点的传输,一个server,一个client,现在想通过千兆网线传输数据,但传输速度太慢达不到要求。 我尝试增大发送端(client)的发送缓冲区大小为1024*1000,接收端的接收缓冲区增大为1024*10000,但传输速度提升的十分有限,几乎没有效果,这是什么原因?是大小设置的不对吗?
LubinLew 2017-07-02
  • 打赏
  • 举报
回复
这个你得具体需求具体分析,增大buff(内核或者传入buff)都是 空间换时间。 多路复用也能提高并发性能。
HW_Coder0501 2017-07-02
  • 打赏
  • 举报
回复
引用 11 楼 lgbxyz 的回复:
当然会返回,要不然要循环干什么
还有一个问题想请教大神,如果想提高socket文件传输的效率,都有什么方法?
加载更多回复(6)

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧