socket传送二进制流的一些总结

第一次实质性的接触socket通讯方面的工做,因此遇到的问题还真很多,写篇博客记录一下,提高下记忆。ios

需求是经过私有协议进行二进制数据的传输,必须保证数据包不能被丢失,因此选择tcp的socket进行通讯。安全

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

   这个是一个想固然的错误。想固然的觉得TCP是有链接的通讯,可是你若是长时间不通讯,服务端一直保持着通讯,这对服务器资源是一种极大的浪费。客户端与服务端的链接是须要占用必定资源的,而服务端的资源是有限的。若是一直保持链接状态,那么你的服务器的性能确定是有问题的。socket

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

 

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

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

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

 

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

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

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

   1)总体压缩,分段发送

   2)分段压缩,分段发送

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

 

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

先是C++的:

 1     string fileName = "D:/XtAmpClient/XtAmpTradeClient_x64_3.0.1.14473.exe";
 2     ifstream ifs(fileName, ios_base::binary);
 3 
 4     filebuf* pbuf = ifs.rdbuf();
 5     int size = pbuf->pubseekoff(0, ios_base::end, ios_base::in);
 6     pbuf->pubseekpos(0, ios_base::in);
 7 
 8     char* buf = new char[size];
 9     pbuf->sgetn(buf, size);
10     ifs.close();
11     delete []buf;

最后是C的:

 1     const char* fileName = "D:/XtAmpClient/XtAmpTradeClient_x64_3.0.1.14473.exe";
 2     FILE* fp = fopen(fileName, "rb");
 3     if (NULL == fp)
 4     {
 5         cout << "open file failed" << endl;
 6         return ;
 7     }
 8 
 9     fseek(fp, 0, SEEK_END);
10     long size = ftell(fp);
11     rewind(fp);
12 
13     char* buffer = (char*)malloc(sizeof(char) * size);
14     if (NULL == buffer)
15     {
16         cout << "malloc failed" << endl;
17         return ;
18     }
19 
20     int ret = fread(buffer, 1, size, fp);
21     if (ret != size)
22     {
23         cout << "reading failed" << endl;
24         return ;
25     }
26 
27     fclose(fp);
28     free(buffer);

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

相关文章
相关标签/搜索