zoukankan      html  css  js  c++  java
  • CAsyncSocket只传输了一部分数据(UDP),后面是乱码

    void CCAsyncSocketDlg::OnBnClickedBtnSend()
    {
        UpdateData(TRUE);
        TCHAR ipstr[INET_ADDRSTRLEN];
        DWORD dwRemoteIp = htonl(m_dwRemoteIp);
        InetNtop(AF_INET, &dwRemoteIp, ipstr, sizeof ipstr));
    
        int nWrite = m_sockLocal.SendToEx(m_strSend.GetBuffer(), m_strSend.GetLength(),
            htons(m_uRemotePort), ipstr);
    }
    void CCAsyncSocketDlg::OnReceive(int nErrorCode)
    {
        UpdateData(TRUE);
        TCHAR buf[4096];
        int nRead;
        CString rAddr;
        UINT rPort;
        while (true)
        {
            nRead = m_sockRemote.ReceiveFromEx(buf, 4096, rAddr, rPort);
            if (nRead > 0)
            {
                buf[nRead] = 0;
                m_strRecv.Append(buf);
            }
            else
            {
                break;
            }
        }
    
        m_strRecv.Append(_T("
    "));
        UpdateData(FALSE);

    上述代码是忽略了错误处理后的代码,其中Dlg类的OnReceive方法是给CAsyncSocket的派生类的OnReceive方法调用的(在此之前派生类保存了Dlg类的指针)。

    由于是UDP套接字,所以不存在粘包问题,SendTo和RecvFrom的返回值是一样的(说明发送和接收的数据大小一样),那么后面部分怎么出错的呢?

    经过多次输入测试,发现每次只有后半部分读取失败。解决方法如下

        int nWrite = m_sockLocal.SendToEx(m_strSend, m_strSend.GetLength() * sizeof(TCHAR),
            htons(m_uRemotePort), ipstr);
                buf[nRead / sizeof(TCHAR)] = 0;

    替换对应位置即可,因为我是传递TCHAR数组(在Unicode下CString是基于TCHAR的,如果用char的话每次CA2W、CW2A还是挺麻烦的),而socket传递的是以字节为单位,对于包含N个字符的TCHAR数组,实际上传输字节数是N*sizeof(TCHAR),所以SendTo函数里第二个参数妖改成sizeof(TCHAR),但是对于接收缓冲区而言,缓冲区是个TCHAR数组,单位大小是sizeof(TCHAR)个字节而不是1个字节,所以计算下标时又要用nRead / sizeof(TCHAR)。

    顺便TCHAR的字符串操作函数相当于就是把strxxx改成了_tcsxxx,比如标准C的strcpy对于TCHAR来说就是_tcscpy,这是微软对Unicode字符操作函数的扩展,见头文件tchar.h

    以及inet_ntop等网络转换函数也变成了InetNtop,见头文件WS2tcpip.h。

    这个类本身使用不难,但是由于书上包括文档有不少东西没说清楚,结果折腾了好久。顺带一提,它的一系列函数使用的IP也好,接口也好,竟然还是要用htons、htonl转换的,唉,真是无语。

  • 相关阅读:
    Demo:刮刮卡橡皮擦效果
    养成良好的代码编写习惯
    我的百科
    专业英语词汇
    加载资源的类
    循环滚动翻页+居中项缩放
    学习笔记—Node中模块化规范
    学习笔记—Node中的EventLoop
    学习笔记—Node的全局对象
    学习笔记—Node的基本概念
  • 原文地址:https://www.cnblogs.com/Harley-Quinn/p/6964705.html
Copyright © 2011-2022 走看看