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[];
int nRead;
CString rAddr;
UINT rPort;
while (true)
{
nRead = m_sockRemote.ReceiveFromEx(buf, , rAddr, rPort);
if (nRead > )
{
buf[nRead] = ;
m_strRecv.Append(buf);
}
else
{
break;
}
} m_strRecv.Append(_T("\r\n"));
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)] = ;
替换对应位置即可,因为我是传递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转换的,唉,真是无语。
CAsyncSocket只传输了一部分数据(UDP),后面是乱码的更多相关文章
- [TCP/IP] 传输层-TCP和UDP的使用场景
传输层-TCP和UDP应用场景 TCP(传输控制协议) 需要将要传输的文件分段传输,建立会话,可靠传输,流量控制 UDP(用户报文协议) 一个数据包就能完成数据通信,不需要建立会话,不分段,不用流量控 ...
- 【知识强化】第五章 传输层 5.2 UDP协议
这节课我们来学习一下UDP协议. 那在上节课呢我们学了这样一个打油诗. 啊,就是传输层有两个好兄弟,大哥TCP和二弟UDP.大哥很靠谱,二弟不靠谱.那只要说到UDP协议我们就要知道它的一个重要的特点, ...
- 1 开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你。 本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的原则已经被许多现有的JDBC应用程序编译运行并验证过。 这些指导原则包括: 正确的使用数据库MetaData方法 只获取需要的数据 选用最佳性能的功能 管理连
1 开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你. 本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的 ...
- Linux rsync配置用于服务器之间传输大量的数据
Linux的rsync 配置,用于服务器之间远程传大量的数据 [教程主题]:rsync [课程录制]: 创E [主要内容] [1] rsync介绍 Rsync(Remote Synchronize ...
- Excel只想显示一部分日期,怎样把其余部分隐藏起来?
问题:只想显示一部分日期,怎样把其余部分隐藏起来? 方法:分列 Step1:选中需要修改的单元格——数据——分列. Step2:固定宽度——点击下一步. Step3:在建立分列处单击鼠标(若想取消 ...
- img只显示图片一部分 或 css设置背景图片只显示图片指定区域
17:14 2016/3/22img只显示图片一部分 或 css设置背景图片只显示图片指定区域 background-position: 100% 56%; 设置背景图片显示图片的哪个坐标区域,图片左 ...
- wcf传输Dataset大数据量 -压缩(一)
wcf传输Dataset大数据量 -压缩(一) 由于WCF不能传输DataTable(不能序列化),所以更多项目中都会使用DataSet作为查询集合的首选返回类型,但是由于DataSet会生成很多的状 ...
- oracle 查询重复数据并且删除, 只保留一条数据
数据库操作中,经常会因为导数据造成数据重复,需要进行数据清理,去掉冗余的数据,只保留正确的数据 一:重复数据根据单个字段进行判断 1.首先,查询表中多余的数据,由关键字段(name)来查询. sele ...
- hbase使用MapReduce操作3(实现将 fruit 表中的一部分数据,通过 MR 迁入到 fruit_mr 表中)
Runner类 实现将 fruit 表中的一部分数据,通过 MR 迁入到 fruit_mr 表中. package com.yjsj.hbase_mr; import org.apache.hadoo ...
随机推荐
- Mutations
蛤蟆可以吃队友,也可以吃对手. 如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true. 举例,["hello", "Hello"]应该返回 ...
- hdu 1079 Calendar Game sg函数 难度:0
Calendar Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- WeChat-扫码支付
官方文档API: 打开连接 主要实现功能,网站上调起 微信支付二维码图片. 所需引用基类API:Data.cs.WxPayApi.cs.HttpService.cs.Config.cs.Thought ...
- JS中apply与call的用法
JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 先来看看JS手册中对call的解释: call 方法调用一个对象的一个方法,以另一个对象替换当前对象. cal ...
- LeetCode OJ:Word Pattern(单词模式)
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...
- LeetCode OJ:Maximal Square(最大矩形)
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...
- SpringXML方式配置bean的生存范围Scope
在一个bean的配置里面可以指定一个属性Scope,也就是bean的范围,bean的生命周期. Scope可取的值5种:singleton(默认).prototype.request.session. ...
- IOS开发 GCD介绍: 基本概念和Dispatch Queue
iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ØN ...
- Uncaught TypeError: Cannot read property 'ownerDocument' of null
/********************************************************************* * Uncaught TypeError: Cannot ...
- Android:BroadcastReceiver
参考:<第一行代码:Android> 郭霖(著) Broadcast分类 注册方式: 动态广播 在代码中注册receiver 一定要手动在onDestroy()时调用unregiste ...