我程序中的一个线程需要发送好几个大的double数组给另外一个程序。线程本身是通过指针得到数组的地址的。现在我不知道怎么方便的发送数组给零位一个程序,并且能把字符类型和double类型互相转换。现在我是每次发送一个数组,并且复制每一个元素的。感觉这是一个超级笨的办法,而且实际用起来速度很慢。
请问我应该怎么做?请大家帮忙。
//发送端
n=0;
for(j=0;j<Ny;j++)
for(i=0;i<Nx;i++)
n += sprintf(sendBuf+n,"%16.10f",u[j][i]);
send(sockConn,sendBuf,n,0);//接收端
n=Nx*Ny*16;
recv(sockClient,recvBuf,n,0);
for(j=0;j<Ny;j++)
for(i=0;i<Nx;i++)
u[j][i]= atof(recvBuf+(j*Nx+i)*16);

解决方案 »

  1.   

    double a[100];char sendbuf[2048];memcpy(sendbuf, a, 100 * sizeof(double));send(..., sendbuf);
      

  2.   

    有两种办法
     1.把 浮点数当作 字符串来传送
     2.直接发送内存缓冲区
       但是直接发送缓冲区会引起一个问题,如果客户端和服务端在不同的cpu体系架构下,发送16位数和32位数和浮点数的时候会引起 数据解释出错。因为 intel cpu,sun sparc cpu,ibm powerpc cpu,dec alpha cpu采用的表示整数和浮点数的方式不一样。有的是高8(16)位在前,有的是低8(16)为在前。所以你在intel cpu windows下发送一个整数“16”或者浮点数到一个采用sparc cpu的solaris系统下,它按照它的内存结构解释出来,就肯定不是16了!这就是所谓的big-endian和little-endian。   如果要直接发送内存缓冲区,则需要将缓冲区打包一下,目前有两种方式。
            1.采用sun rpc里边的数据打包格式  External Data Representation(Sun's XDR Package)
            2.采用corbo标准的Common Data Representation (CDR)
            前一个被firebird开源数据库采用,后一个是ACE使用的跨平台数据打包格式.
            都可以找到示例代码。
      

  3.   

    如果你比较急,并且通信双方在同一cpu体系架构下。
    可以直接发送缓冲区,不过这样的话,你的服务器就不是“跨平台”的了。直接发送缓冲区代码如下
    int dim1 = 5;
    SOCKET s;double (*pia)[512] = new double[dim1][512];
    send(s,reinterpret_cast<const char *>( pia),dim1*512*sizeof(double),0);服务器端接受到后再进行指针转换
      

  4.   

    u【Ny】【Nx】
    //发送端
    n=Nx*Ny*sizeof(double);
    memcpy(recvBuf,(char*)(u[0]),n);
    if(n != send(sockClient,recvBuf,n,0))
         break;//接收端
    n=Nx*Ny*sizeof(double);
    recv(sockConn,sendBuf,n,0);
    memcpy((char*)(u[0]), sendBuf, n);我用这种方法发送成功了,在单机上模拟可以。但是好像在两台机器上(同一结构)有问题。
      

  5.   

    直接发送缓冲区代码如下
    int dim1 = 5;
    SOCKET s;double (*pia)[512] = new double[dim1][512];
    send(s,reinterpret_cast<const char *>( pia),dim1*512*sizeof(double),0);服务器端接受到后再进行指针转换
    代码如下size_t readn(SOCKET fd, char *vptr, size_t n)
    {
    size_t nleft;
    size_t nread;
    char *ptr; ptr = vptr;
    nleft = n;
    while (nleft > 0) {
    if ( (nread = recv(fd, ptr, nleft,0)) == SOCKET_ERROR) {
    return(-1); //error
    } else if (nread == 0)
    break; nleft -= nread;
    ptr   += nread;
    }
    return(n - nleft); //succ recv n
    }char sz_recv_buf[5*512*sizeof(double)]={0};
    int nRet;
    double **myp;nRet = readn(sockConn,sz_recv_buf,5*512*sizeof(double));
    if (nRet == -1)
    {
    //错误处理
    }
    else
    {
    myp = reinterpret_cast<double **>(sz_recv_buf);
    int i,j;
    for (i=0;i<5;i++)
    {
    for (j=0;j<512;j++)
    printf("value is %d \t\n",myp[i][j]);
    }
    }
      

  6.   

    anjuta_c(天天学习不退步)
     1.采用sun rpc里边的数据打包格式  External Data Representation(Sun's XDR Package)
     2.采用corbo标准的Common Data Representation (CDR)这两种办法我怎么都没有找到相应的资料。我对这挺有兴趣。
      

  7.   

    cdr 参看 《advanced corba programming with c++》13.3节或者《c++ network programming》。cdr的实现在ace中有实现的类,使用很方便,参看ace中的示例代码。xdr 参看 http://www.faqs.org/rfcs/rfc1014.html,在firebird里边有个xdr的实现和使用代码,如果感兴趣,可以下载下来看。google上编都可以搜索到啊,怎么会找不到呢?