网络编程:send/write强制发送所有数据

send通过socket发送数据的时候,不能保证发送的数据在网络传输过程中,能一次传输到接收端。

send发送的数据,只是将应用层数据发送给kernel的缓冲区,而kernel缓冲区接收到应用层的数据之后,会根据当前自身的状态来确定如何发送接收的数据。具体业务逻辑,见<http://blog.csdn.net/russell_tao/article/details/9370109>

而此处想强调的是,将send发送的所有数据强制发给kernel缓冲区之后,才继续下一步的操作。

非常简单的业务需求

代码实现:

0)设置一个标记 nTotalLength,记录send成功发送数据的长度

1)开启一个for循环(while也可以)

2)设定循环发送的最大次数

3)调用send发送你想发送的全部数据 nLength

4)跟踪发送到kernel缓冲区的数据大小

5)判断发送返回值:如果断开连接或出错,则停止发送,并记录当前错误信息

6)如果条件5)正常,则更新标记 nTotalLength  

7)判断数据是否发送完毕,nTotalLength 和 nLength 相等,退出循环,否则,继续发送

c/c++ code:

HRESULT SendTotal(SOCKET sock, PCHAR pszSend, int nLength, int *pnActualLength)
{
    TRACE_FN_SCOPE;

    HRESULT hResult = E_FAIL;

    int nTotalLength = 0, nSentLength = 0;

    TRACE(INFO, L"Send Data Length:%d", nLength);
    //forces to send all bytes until error or socket shutdown

    for (int nLoopCount = 0; ; nLoopCount++)
    {
        if (nLoopCount > MAX_LOOP_COUNT)
            ERROR_ESCAPE(TRUE, E_FAIL, L"Too many loops");

        TRACE(INFO, L"Intended send length; %d", nLength - nTotalLength);
        nSentLength = send(sock, pszSend + nTotalLength, nLength - nTotalLength, 0);
        TRACE(INFO, L"Sent length: %d", nSentLength);
        ERROR_ESCAPE(nSentLength == 0 || nSentLength == SOCKET_ERROR, 
            ::WSAGetLastError() ? ::WSAGetLastError() : E_FAIL, L"Check send length");

        nTotalLength += nSentLength;

        if(nTotalLength == nLength)
            break;
    }

    hResult = S_OK;

_err:
    if (pnActualLength != NULL)
        *pnActualLength = nTotalLength;
    TRACE(INFO, L"Total sent length: %d/%d", nTotalLength, nLength);

    return hResult;
}

---end---


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值