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