在c ++中通过套接字接收二进制数据

时间:2014-02-17 10:52:00

标签: c++ linux sockets binary

我有一个连接到本地网络的MCU单元。该设备通过TCP套接字每秒发送100次状态数据。在同一个套接字上,我也可以发出命令和数据。

我正在尝试编写一个简单的TCP客户端,可以连接到设备,获取数据,如果请求发送命令。目前我可以毫无问题地发送命令(命令作为字符串发送,这是有效的)。我的问题是从设备接收数据。

我从设备手册中知道数据首先应该是32位整数,然后是大约30个双精度数组

我正在建立一个新线程,我想要连续拦截数据并处理它:

void *com::setListenerSocket(void* threadSocketData) {
        struct socketData *sockData;
        sockData = (socketData*)threadSocketData;
        com::tcp_client cListener;

        struct timeval timeout;
        timeout.tv_sec=0;
        timeout.tv_usec=12500;

    //  setsockopt(cListener, IPPROTO_TCP, SO_RCVTIMEO, (char *)timeout, sizeof(timeout)); //no effect
        cListener.connect(sockData->host , sockData->port);
        cout << "listener thread started" << endl;
        cout << "host=" << sockData->host << " at port=" << sockData->port << endl;

        cListener.send_data("Listener Reporting\n");
    while(listenerRun){
        listenerHB++;
        cout << endl <<"*****************************       BGN     *************************************************************"<< endl;
        char *received = new char[PACKETSIZE];
        cListener.receive(PACKETSIZE, received);
        unsigned int test;
        test = (uint32_t) received;
        cout << "received=" << test << endl;
        for(int i = 0; i< PACKETSIZE ; ++i)
          cout << received[i] << ", ";
        cout << endl <<"*****************************       END     *********************************************"<< endl;
        robotPacket data;
        //parseData(received, &data);
        //usleep(1 MS);
    }
    cout << "listener signing out" << endl;;
    pthread_exit(NULL);
}

,监听器方法是:

void com::tcp_client::receive(int size, char* buffer) {

  unsigned int bytecnt = 0, archive = 1;

  while(bytecnt < (unsigned int)size) {
//     bytecnt += recv(sock , &buffer[bytecnt] , size-bytecnt , 0); 
    bytecnt += recv(sock , buffer , size-bytecnt , MSG_WAITALL); 
  }

  unsigned int test;
  test = buffer[0];
  cout << "value=" << test << "¤" << endl;
  }

我将指针指向缓冲区的开头并将其转换为uint32_t,但结果完全错误(我知道它应该是数据包长度,但它很容易进入数百万)

当我使用nl命令时: nc -l 12354我可以在我的程序中写入文本,一切正确

编辑:与更有经验的人会面: 解决:我不能自己发布解决方案,所以我会把它放在这里以防有人遇到类似的问题。

首先,我希望套接字能够自动处理单个传输开始的位置以及结束的位置 - 这是不正确的,正如Basyle Starynkevitch指出的那样。但是,TCP确保数据按顺序进行并且没有任何丢失,因此我可以安全地假设承诺的500字节我将获得500字节或其他任何内容。

其次,数据是以大尾数形式出现的 - 巴塞尔也指出了这一点。我做了一点点转移,但仍然有错误的结果,但......

最后,我遇到了类型转换的另一个问题。我使用char *而数据是unsigned char。 用unsigned char *替换缓冲区char *解决了解码问题。

对于那些与通过局域网进行通信的旧电子设备接口的人来说,这可以是一个解决方案。

如果有人以简洁的形式发布我上面写的内容,我想这个案例可以被认为是关闭的。

1 个答案:

答案 0 :(得分:0)

您可能想要查看tcpclient(http://cr.yp.to/ucspi-tcp/tcpclient.html)。您可以在tcpclient下运行您的C / C ++程序 - 即tcpclient将生成您的程序并打开与服务器的tcp连接,并将程序的stdout传送到服务器,并将服务器的输出管道输出到程序的stdin。这样做的好处是你可以让tcpclient完成所有繁重的任务,就像设置套接字等一样,你可以专注于你的程序的核心功能。