socklen_t sendbuflen = 0; socklen_t len = sizeof(sendbuflen); getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len); printf("default,sendbuf:%d\n", sendbuflen); sendbuflen = 10240; setsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, len); getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len); printf("now,sendbuf:%d\n", sendbuflen); |
,发送应用程序会收到socket可读的信号(通常是select调用返回socket可读),但在读取时会发现recv函数返回0,这时应该调用close函数来关闭socket(发送给对方ack);
还是谢谢版主了,我的第一精...
原帖由 flw 于 2007-7-31 09:51 发表
【在阻塞模式下,send函数的过程是将应用程序请求发送的数据通过socket尽能力发送到对方接收缓存中(并非对方应用程),并返回成功发送的大小;】
这句话是错的吧?
我认为即使是在阻塞方式下,只要发送缓冲区还 ...
原帖由 flw 于 2007-7-31 10:22 发表
但那时 write/send 已经返回了。
它并不会等待发送结果的。
发送是 TCP 软件的功能,
write/send 只否则交付,
并不关心结果。
原帖由 思一克 于 2007-7-31 10:43 发表
send后,KERENL回立即启动dev发送.
write/send不会等待数据是否成功到达对方。
即使返回成功也不代表数据成功到达。
但返回错误却代表数据没有到达。
原帖由 思一克 于 2007-7-31 10:53 发表
但是send/write不是“仅仅负责COPY到本地buffer"其它就不管了(就交给TCP了),
send/write(网络)的内核代码多部分也属于TCP本身。
它们要启动实际发送,还要尽最大努力检查网络连接的状态,返回许多网络的 ...
原帖由 cookis 于 2007-7-31 09:45 发表
绝世好贴...
有一点不明白...
发送方也要用select吗..那岂不是每一次发送前都要用select轮循一下..我一般就是send 返回 -1就表示对方关闭(或网络中断)
原帖由 思一克 于 2007-7-31 11:11 发表
本机发出的报文
(route if need)dev_queue_xmit |
ip_finish_output2 |<POSTROUTING> ip_finish_output | ip_output | ip_dst_output | <LOCALOUT> ip_push_pending_frames | raw_sendmsg | inet_sendmsg | sock_sendmsg | sys_sendmsg | sys_socketcall | sysenter_past_esp
原帖由 flw 于 2007-7-31 09:51 发表
【在阻塞模式下,send函数的过程是将应用程序请求发送的数据通过socket尽能力发送到对方接收缓存中(并非对方应用程),并返回成功发送的大小;】
这句话是错的吧?
我认为即使是在阻塞方式下,只要发送缓冲区还 ...
原帖由 flw 于 2007-7-31 09:59 发表
【如果发送应用程序没有处理这个可读的信号,而是继续调用send,那么第一次会像往常一样继续填充缓存区,然后返回,但如果再次调用send,进程会收到SIGPIPE信号,该信号的默认响应动作是退出进程.】
这个也不对。
我认为这个不是第一次还是第二次的问题,
而取决于发送端是否已经收到了对方的 FIN 包,
如果收到了就会 SIGPIPE 或者 EPIPE,
否则正常发送,不会出错。
原帖由 醉卧水云间 于 2007-7-31 11:16 发表
也请你自重,不知道不要乱说误导别人。
你也应该知道我非常不喜欢你,不要忘记是怎么卸掉本版斑竹的,你有生杀大权,我可以不要ID。
就凭你来审视我,笑话!你当你是老胡啊?想想你算老几再说这种居高 ...
原帖由 yulc 于 2007-7-31 11:19 发表
我的测试结果是,当接收端主动关闭后,发送应用程序调用send,但在这个send之前,即使发送端已经收到了对方的FIN包,应用程序也不会得到SIGPIPE,而仅仅是返回-1的结果,同时,会将errno置为对端已关闭的那个宏(我 ...
原帖由 思一克 于 2007-7-31 11:24 发表
好象不是你说的这样。
你可以实验,写一个阻塞的TCP,先send 1 个字节(1次),成功后将NIC 拔掉,然后再SEND 1个字节(2次), 然后再1个字节(3次)
2次可以返回成功的。3次失败。
该问题同原来争吵 ...
原帖由 醉卧水云间 于 2007-7-31 11:48 发表
你这是欺骗系统的方式,拔掉网线后系统知道被拔是需要时间的。你可以等一段时间再发送试试,结果应不同。
还有就是系统因为效率上的原因,没有严格按send语意来做,send语意就是返回成功就是保证发送成功 ...
原帖由 思一克 于 2007-7-31 11:58 发表
man send.
RETURN VALUE
On success, these calls return the number of characters sent. On error, -1 is
returned, and errno is set appropriately.
成功代表内容被成功地传输到 ...
原帖由 思一克 于 2007-7-31 11:58 发表
man send.
RETURN VALUE
On success, these calls return the number of characters sent. On error, -1 is
returned, and errno is set appropriately.
成功代表内容被成功地传输到 ...
原帖由 cookis 于 2007-7-31 12:20 发表
各位大师..讨论之余能否给一些经验值...在视频传输应用中,非阻塞的情况下sendbuf_len or recvbuf_len 在TCP UDP下通常设为多大
原帖由 福瑞哈哥 于 2007-7-31 12:49 发表
在阻塞模式下,如果发送包大于缓冲区长度,那中间肯定有一次要把发送端缓冲区的数据通过网络传送到接受端缓冲区。如果这时网络或者对端有问题,send会失败。
还有在发送端已知对方关闭或连接断掉的情况,sen ...
原帖由 思一克 于 2007-7-31 10:43 发表
send后,KERENL回立即启动dev发送.
write/send不会等待数据是否成功到达对方。
即使返回成功也不代表数据成功到达。
但返回错误却代表数据没有到达。
原帖由 醉卧水云间 于 2007-7-31 13:14 发表
所来说去,buffer在这里起重要作用。
阻塞send本意是要发到对方确认的,但唯独buffer能容纳的那部分它不会被立刻发出确认。但它的主意很显然是一个需要对方确认的发送。
原帖由 醉卧水云间 于 2007-7-31 13:27 发表 我觉得这样更好一些:
阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分包将少后0.x秒发送出去,因为有这部分数据的存在,我们建议你不要信任send返回值,如果你依赖于这个返回值,比如发完数据检查返回正常立即关闭连接,则把发送缓冲设置为0会更稳妥。
原帖由 醉卧水云间 于 2007-7-31 13:27 发表
我觉得这样更好一些:
阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分 ...
原帖由 醉卧水云间 于 2007-7-31 13:27 发表
我觉得这样更好一些:
阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分 ...
原帖由 醉卧水云间 于 2007-7-31 13:27 发表
我觉得这样更好一些:
阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分 ...
原帖由 icydancer 于 2007-7-31 14:42 发表
哦?没有buffer?只有sk_buff?不解!
1.skb的确是个管理结构,但是它也有指向数据buffer的指针
2.buffer是的确存在的。要不tcp窗口管理的是什么?
3.据我所知,每个skb结构只管理一个包。(不考虑分片)跟buf ...
原帖由 思一克 于 2007-7-31 14:17 发表
TCP阻塞send是可靠发送,意思是如果连续send成功返回,那么本次send之前的是可靠发送了的。而刚才(本次)的还是不知道。
拔NIC电缆的实验已经证明了。
还有KENREL中其实没有一个专门为了缓冲发送内容的的 ...
原帖由 醉卧水云间 于 2007-7-31 14:53 发表
我记得win下可以设置缓冲为0,不过也不敢肯定,还真没这么设置过,能不能设置为0和系统实现有关,逻辑上没有一点问题,没有缓冲你就直接发应用程序里的数据嘛。如果linux不允许0缓冲,那可能是没考虑给用户 ...
原帖由 yulc 于 2007-7-31 15:49 发表
对的,如果拨掉对端网线的话,在本次send之前的几次send,也还在本地缓存中...
但数据实际上发到网络上去了,只是没有得到ack确认,所以缓存中并没有删除它们...
15:59:56.663510 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712595 108716367> 15:59:56.663522 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1449:2897(1448) ack 1 win 1460 <nop,nop,timestamp 178712595 108716367> 15:59:56.866018 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712646 108716367> 15:59:57.274042 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712748 108716367> 15:59:58.090094 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712952 108716367> 15:59:59.722196 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178713360 108716367> 16:00:02.986402 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178714176 108716367> |
原帖由 yulc 于 2007-7-31 16:24 发表
不知道这个答复能不能说清楚.
我将192.168.0.229做为发送端, 192.168.0.226做为接收端,
当双方建立tcp后,将226主机的网线拨掉,在229上用tcpdump得出的结果是:
15:59:56.663510 IP 192.168.0.229.3 ...
原帖由 福瑞哈哥 于 2007-7-31 16:33 发表
兄弟,你的这个系统发送了数据不代表所有的系统都会在send时发送啊。
如果前面的结论是正确的话,就是说send只负责拷贝数据到缓冲区,内核tcp负责发送,那就有可能在send返回后没有发送啊。
原帖由 yulc 于 2007-7-31 16:43 发表
"这个不能说明啊,因为现在想知道的是send返回时,是数据包发到网络的标志,还是送到buffer的标志。"
这个我认为要看当前发送端是什么状态,如果之前还有包没有得到确认,那么此次send肯定仅仅是送到buffer.
...
原帖由 baohuaihuai 于 2007-7-31 16:45 发表
各位顺便讲解一下这个的过程(假设接收缓冲区和发送缓冲区都是8K,网络情况良好):
time1:发送端send 8K,接收端应用程序不recv
time2:接收端recv 2K.
time3:发送端send 8K.
time4:接收端recv 14K.
原帖由 yulc 于 2007-7-31 16:54 发表
结果:
time1: 发送端将8k数据分为N个数据包发送到了接收端的缓存中,接收端等待应用程序recv;
time2: 接收端收到了2k,缓存中还有6k;
time3: 发送端又将8k数据分N个包到接收端的接收缓存中;
time4: 接收 ...
原帖由 icydancer 于 2007-7-31 16:52 发表
有关系,现在大家想知道的是,send是将数据发到网络后再返回?还是仅仅将数据放到buffer后就马上返回?
你上面的数据不能说明这一点
原帖由 xiaxueyi 于 2007-7-31 17:57 发表
你们讨论得这么复杂,我问个简单的问题
在非阻塞的情况下,应用程序调用send发送数据后返回,在不与接收端再次通讯的情况下,如何知道内核有没有把发送端缓冲区的数据发出去?如果没有,如何知道错误原因?
原帖由 benjiam 于 2007-7-31 17:41 发表
好像没什么意义啊!
所谓的拔网线测试更是奇怪了。 没有意义。
在阻塞和非阻赛的时候 send 没什么区别的, 都是copy 栈里面。 就返回了。 没什么区别
关键在recv
原帖由 flw 于 2007-7-31 09:51 发表
【在阻塞模式下,send函数的过程是将应用程序请求发送的数据通过socket尽能力发送到对方接收缓存中(并非对方应用程),并返回成功发送的大小;】
这句话是错的吧?
我认为即使是在阻塞方式下,只要发送缓冲区还 ...
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |