zoukankan      html  css  js  c++  java
  • socket传送二进制流的一些总结

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

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

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

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

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

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

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

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

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

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

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

       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++的代码明显更简洁。

  • 相关阅读:
    PHP 上传与下载
    PHP OOP 魔术方法
    PHP的错误处理
    初识PHP
    MUI实现上拉刷新和下拉加载
    解决 windows npm ERR! asyncWrite is not a function 问题
    浅谈angular2与angularJS的区别
    AngularJS内建服务以及自定义服务的用法
    mysql与mysqli的一些区别和方法
    数据库基础和三大范式以及基本的增删改查命令
  • 原文地址:https://www.cnblogs.com/zhugaopeng/p/9688882.html
Copyright © 2011-2022 走看看