为什么TCP socket实际使用时,对较大的数据要分多次发送

bloodykapok 2015-01-07 09:37:09
我是做网络仿真和试验床开发的,最近需要用到TCP的传输机制,图方便就用IP协议栈下现成的TCP socket了。
遇到一个问题,我希望一次性传输1M~100M左右的数据,并设置了相应的收发缓冲大小(我的小内存条啊好蛋疼...)。可是在传输这个超大BUF的时候,常常会出现传不完的情况。

看网上贴的小型示例代码往往是循环分段发送的,如:
while(1)
{
send(xx,xx,xx,xx);
}
的形式。

并不是一次性send一个超大的BUF

为什么呢?
...全文
462 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 3 楼 mymtom 的回复:
send 不保证发送完全部数据的,只是返回发送的已经发送的字节数。 RETURN VALUES The call returns the number of characters sent, or -1 if an error occurred. 需要自己写个循环,保证所有数据都发送完成。 用unp上的writen函数吧

ssize_t                     /* Write "n" bytes to a descriptor. */  
writen(int fd, const void *vptr, size_t n)  
{  
    size_t      nleft;  
    ssize_t     nwritten;  
    const char  *ptr;  
  
    ptr = vptr;  
    nleft = n;  
    while (nleft > 0) {  
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {  
            if (nwritten < 0 && errno == EINTR)  
                nwritten = 0;       /* and call write() again */  
            else  
                return(-1);         /* error */  
        }  
  
        nleft -= nwritten;  
        ptr   += nwritten;  
    }  
    return(n);  
}  
/* end writen */  
what if I replaced write in the function above with send? Here is the man 2 send The only difference between send() and write() is the presence of flags. With zero flags parameter, send() is equivalent to write().
bloodykapok 2015-01-08
  • 打赏
  • 举报
回复
谢谢楼上的回答 问题已解决 更好地理解了TCP socket的机制 结贴给分
zuxi 2015-01-07
  • 打赏
  • 举报
回复
这个跟MTU和MSS有关系,就像公路上并不是一下子所有汽车都能通行一个道理。 如果是阻塞send的话,就用不着while循环多次调send了,send会等待把所有的buf拷贝到内核发送缓冲区才返回。如果是非阻塞send的话,send调用会拷贝数据到内核发送缓冲区后就返回,如果发送的数据太大而发送缓冲区太小,你就需要while循环判断每次拷贝了多少到缓冲区还有多少没有拷贝,之后再次调send把剩下的数据拷贝到发送缓冲区。
奔跑的路 2015-01-07
  • 打赏
  • 举报
回复
MSS MTU
mymtom 2015-01-07
  • 打赏
  • 举报
回复
send 不保证发送完全部数据的,只是返回发送的已经发送的字节数。 RETURN VALUES The call returns the number of characters sent, or -1 if an error occurred. 需要自己写个循环,保证所有数据都发送完成。 用unp上的writen函数吧

ssize_t                     /* Write "n" bytes to a descriptor. */  
writen(int fd, const void *vptr, size_t n)  
{  
    size_t      nleft;  
    ssize_t     nwritten;  
    const char  *ptr;  
  
    ptr = vptr;  
    nleft = n;  
    while (nleft > 0) {  
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {  
            if (nwritten < 0 && errno == EINTR)  
                nwritten = 0;       /* and call write() again */  
            else  
                return(-1);         /* error */  
        }  
  
        nleft -= nwritten;  
        ptr   += nwritten;  
    }  
    return(n);  
}  
/* end writen */  

23,121

社区成员

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

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