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 ...
随机推荐
- JavaScript---js的模块化
js的模块模式被定义为给类提供私有和公共封装的一种方法,也就是我们常说的“模块化”. 怎么实现“模块化”? 通过闭包的原理来实现“模块化” ,具体实现:1.必须有外部的封闭函数,该函数必须至少被调用 ...
- shiro的三大功能
1.提供的功能
- kvm虚拟主机安装速度很慢
在c6220 II上部署虚拟化遇到的问题: 1.部署完kvm后,安装虚拟主机的过程非常缓慢,但是最终能成功 原因:宿主机BIOS的virtualization technology设置为Disable ...
- MVC和EF中的 Model First 和 Code First
准备:先引入MVC和EF的dll包 *命令方法:打开工具——库程序包管理器——程序包管理器控制台,选择自己的项目 a) Install-Package EntityFramework -Ver ...
- log4cpp安装
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- vux配置i18n
根据使用文档,先引入i18n import VueI18n from 'vue-i18n'; Vue.use(VueI18n) const i18n = new VueI18n({ locale: ' ...
- TeamView
1.TeamView TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamV ...
- python3精简笔记(二)——函数
函数 下面的地址可以查看函数: https://docs.python.org/3/library/functions.html 也可以在交互式命令行通过help()查看函数的帮助信息. 如: > ...
- Python matplotlib 数据分布
利用plt.hist() import matplotlib.pylab as plt %matplotlib inline plt.figure(figsize=(21, 12)) plt.hist ...
- java中高级面试题整理及参考答案
面试问题: 一.Java基础方面: 1.Java面相对象的思想的理解(主要是多态): http://blog.csdn.net/zhaojw_420/article/details/70477636 ...