第一次实质性的接触socket通信方面的工作,所以遇到的问题还真不少,写篇博客记录一下,提升下记忆。

需求是通过私有协议进行二进制数据的传输,必须保证数据包不能被丢失,所以选择tcp的socket进行通信。

1. 遇到的第一个问题是客户端与服务端的socket通信没有保持持续的连接状态

这个是一个想当然的错误。想当然的以为TCP是有连接的通信,但是你如果长时间不通信,服务端一直保持着通信,这对服务器资源是一种极大的浪费。客户端与服务端的连接是需要占用一定资源的,而服务端的资源是有限的。如果一直保持连接状态,那么你的服务器的性能肯定是有问题的。

解决这个问题的办法是保活。服务端发送心跳包,客户端接受到之后进行回应。客户端告诉服务器,还在线,不要断开连接。如果客户端长时间没有回应,服务器断开与此客户端的连接,减少资源占用。

2. 二进制文件的读写问题

第一次尝试读取二进制文件采取了分段读取的方式。测试过程中发现一个很大的问题:文件读取到部分就会中断读取。debug下,得出是读取到了空字符('\0')。这个直接导致一次读取到内容在发送前丢失,甚至有些情况下会有空字符,客户端接受时会产生崩溃现象。

既然分段不行,就干脆全部读取,然后在分段发送。boost.asio库支持对vector包装发送,分段发送时,把一块二进制流拷贝到vector中,然后整体发送。

3. 提高二进制流的传输效率

直接传输二进制流不是一个高效的行为,也不是一个安全的行为。直接发送一个二进制流很容易被截获,从而导致信息泄露。

提高二进制流传输效率的办法就是加密压缩再发送。服务器加密压缩,客户端解密解压缩。可采取两种方式:

1)整体压缩,分段发送

2)分段压缩,分段发送

要求不是很高的话,采取方式一比较好。简单粗暴。。

贴一些代码,整体读取二进制文件的:

先是C++的:

     string fileName = "D:/XtAmpClient/XtAmpTradeClient_x64_3.0.1.14473.exe";
ifstream ifs(fileName, ios_base::binary); filebuf* pbuf = ifs.rdbuf();
int size = pbuf->pubseekoff(, ios_base::end, ios_base::in);
pbuf->pubseekpos(, ios_base::in); char* buf = new char[size];
pbuf->sgetn(buf, size);
ifs.close();
delete []buf;

最后是C的:

     const char* fileName = "D:/XtAmpClient/XtAmpTradeClient_x64_3.0.1.14473.exe";
FILE* fp = fopen(fileName, "rb");
if (NULL == fp)
{
cout << "open file failed" << endl;
return ;
} fseek(fp, , SEEK_END);
long size = ftell(fp);
rewind(fp); char* buffer = (char*)malloc(sizeof(char) * size);
if (NULL == buffer)
{
cout << "malloc failed" << endl;
return ;
} int ret = fread(buffer, , size, fp);
if (ret != size)
{
cout << "reading failed" << endl;
return ;
} fclose(fp);
free(buffer);

性能上C比C++好一点点,但是C++的代码明显更简洁。

socket传送二进制流的一些总结的更多相关文章

  1. 转:WCF传送二进制流数据基本实现步骤详解

    来自:http://developer.51cto.com/art/201002/185444.htm WCF传送二进制流数据基本实现步骤详解 2010-02-26 16:10 佚名 CSDN   W ...

  2. Linux网络中接收 "二进制" 流的那些事 --- 就recv的返回值和strlen库函数进行对话

    1.    前言 很多朋友在做网络编程开发的时候可能都遇到这样的问题,在进行接收二进制流的数据的时候,使用strlen库函数来得到 二进制数据长度的时候并不准确.为什么呢??首先,使用strlen进行 ...

  3. socket传送文件格式的问题

    在python3中socket传送文件只能传送‘bytes'类型,如下例子: import socket client = socket.socket()client.connect(("l ...

  4. C#二进制流的序列化和反序列化

    public class BinaryHelper { /// <summary> /// 将对象序列化为byte[] /// 使用IFormatter的Serialize序列化 /// ...

  5. [PHP][位转换积累]之与运算截取二进制流的值

    function getBit( $num, $bit, $mask ){ return $num>>$bit&$mask; } var_dump( getBit( 41, 3, ...

  6. c#中文件与二进制流文件的转换

    将文件转换成二进制方法: /// <summary>    /// 将文件转换成二进制    /// </summary>    /// <param name=&quo ...

  7. Python中对字节流/二进制流的操作:struct

    前言 前段时间使用Python解析IDX文件格式的MNIST数据集,需要对二进制文件进行读取操作,其中我使用的是struct模块.查了网上挺多教程都写的挺好的,不过对新手不是很友好,所以我重新整理了一 ...

  8. [.net 面向对象程序设计进阶] (9) 序列化(Serialization) (一) 二进制流序列化

    [.net 面向对象程序设计进阶]  (9)  序列化(Serialization) (一) 二进制流序列化 本节导读: 在.NET编程中,经常面向对象处理完以后要转换成另一种格式传输或存储,这种将对 ...

  9. 如何显示二进制流的图片(利用img控件)

    之前在http://www.cnblogs.com/JsonZhangAA/p/5568575.html博文中是利用的image控件来显示的二进制流图片,我现在想的是能 通过普通的<img id ...

随机推荐

  1. Java基础13-数组算法

    1.数组的复制 //复制算法,将arr1数组的值复制给arr2数组 import java.util.Arrays; public class Test1{ public static void ma ...

  2. python3.4 x86_64-linux-gnu-gcc Error

    running install    running build    running build_py    creating build    creating build/lib.linux-x ...

  3. Dedecms当前位置(面包屑导航)的处理

    一.修改{dede:field name='position'/}的文字间隔符,官方默认的是> 在include/typelink.class.php第101行左右将>修改为你想要的符号即 ...

  4. javascript document.referrer 用法

    document对象的referrer属性,返回导航到当前网页的超链接所在网页的URL. 举例: 1. a.html文件内容如下: <a href="b.html">浏 ...

  5. struts2的java.lang.NoSuchMethodException异常处理

    1. 你有没有试试看 其它的方法能不能用,要是都是这种情况的话,可能是你的Action类没有继承structs里面的DispatchAction或者其它的类.还有你注意下方法的参数列表,类型顺序要正确 ...

  6. vue中 eCharts 自适应容器

    在 vue 脚手架开发中,echarts图表自适应容器的方法: 父组件: <template> <div class="statistics_wrap"> ...

  7. ionic1跨域问题

    在使用ionic是遇到跨域问题 我自己尝试简单的单间一个能返回数据的后台服务器,ionic的www目录我使用一个ionic的livereload 来当做一个简易的web服务器,在使用ionic ser ...

  8. NoSQL(Not Only SQL)

    Everything has its properties and has relation with each other. All in world can be related to each ...

  9. Azure进阶攻略 | 该如何唤醒你?因内核超时而沉睡的Linux虚拟机!

    周五下午,当你收拾好东西准备下班,奔赴 Happy Hour 时,突然接到开发团队的电话: 对方:伙计救命啊,我在搭建开发环境,但 Azure 上的 Linux 虚拟机无法启动! 你(心里想着:你要加 ...

  10. sql数据库常用操作

    string connectionString = @"Data Source=(local)\sql2008r2;Initial Catalog=Movies;Uid=sa;Pwd=sql ...