打包并通过socket -Serialization发送二进制数据的麻烦

时间:2012-11-06 15:40:46

标签: c sockets serialization

我有几个小时的尝试,调试和哭泣希望让我的程序正确发送/打包和接收/解压缩我的数据。我唯一的希望是一些很好的帮助!

打包/解包数据我实施了 Beej的网络编程指南 example pack2.c

代码工作pack / unpack在同一程序内部工作。但是当我尝试通过套接字将打包数据发送到同一台计算机上的另一个程序时,它将无法正常工作!我的想法是recv()和send()函数可能会使数据损坏或类似这样,我试图调试这有几种方法:

我需要一些帮助来实现这一点,我相信问题在于发送和接收buf的方式,因为pack()/ unpack()函数在程序内部工作。

由于

客户端:

unsigned char buf[1024];

    int16_t packetsize = pack(buf, "h", (int16_t)37);
    packi16(buf+1, packetsize);
    int len = packetsize;

    uint16_t header = htons(packetsize); //Convert from host -> network

    //Sends info to receiver about next pack coming.

    printf("HEADER SIZE %d\n", packetsize);

    if(send(sock, &header, packetsize, 0) == -1) {
        perror("sendall");
    }


    /*==========SEND PACKAGE======================*/

    int bytessendt = send(sock, buf, len, 0);//server_send_all(sock, buf, &len);

    if(bytessendt == -1) {
        perror("sendall");
    }

    printf("BYTES SENT OVER SOCKET: %d \n", bytessendt);


    close(sock);

服务器端:

                uint16_t buf;
                int len = sizeof(buf);

                if(recv(i, &buf, len, 0) == -1) {
                    printf("****Error when receiving");
                }

                int header = ntohs(buf);

                printf("HEADER SIZE: %d\n", header);

                /*========REICIVE PACK AND UNPACK================*/

                unsigned char buf2[1024];
        int16_t monkeycount;

                int bytesreaded = recv(i, buf2, header, 0);

                if(bytesreaded == -1) {
                    printf("Feil ved mottakelse\n");
                }

                printf("BYTES READED: %d\n", bytesreaded);
                printf("BYTES SHOULD BE READED: %d\n", header);

                unpack(buf2, "h", &monkeycount);


                printf("CONTENT: %d\n", monkeycount);


                close(i);

int server_send_all(int socket, unsigned char *buf, int *len) {

    int total = 0;              //Total amout of data to send
    int bytesleft = *len;       //Amount of data left to send
    int n;                      //Holds return from send()

    printf("SOCKET -DATA TO SEND: %d\n", *len);

    while(total < *len) {
        n = send(socket, buf+total, bytesleft, 0);

        if(n == -1) { //send() returns error
            break;
        }

        total += n;
        bytesleft -= n;
    }

    *len = total; //Returns actually sent

    return n == -1?-1:0;
}

发送字符串

来自客户:

int packetsize = 0;
packetsize += pack(buf + packetsize, "h", (int16_t)37);
packetsize += pack(buf + packetsize, "s", "Hello World");

    send(sock, &header, packetsize, 0) 

到服务器:

     char s2[30];
                        unpack(buf2, "h30s", &monkeycount, s2);                  

                        printf("CONTENT: %d %s\n", monkeycount, s2);

提供输出

内容:37 Hello Wor

2 个答案:

答案 0 :(得分:2)

解压缩代码需要int *参数来解包int16_t:将您的声明更改为int monkeycount;

答案 1 :(得分:1)

你打包int16_t 2个字节,然后你只用{em> 1个字节递增buf,那应该是2个字节:

int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+2, packetsize);

每次将某些内容打包到缓冲区时,您应该在再次调用pack()时将缓冲区指针递增该量:

pack(buf, 2 bytes);
pack(buf+2, 4 bytes);
pack(buf+6, 2 bytes);
...

所以我认为你应该这样做:

int packetsize =0;
packetsize += pack(buf+packetsize, "h", (int16_t)37);
packetsize += pack(buf+packetsize, "h", (int16_t)38);
...

注1 packetsize应该是int,因为pack()会返回int,我不明白为什么要使用packi16() 1}}第二次而不是更通用的pack()函数。

Note2 :此外,数据包大小错误,您忘记添加packetsize的大小。事实上,我认为你根本不想将数据包大小添加到数据包中,因为你要分别发送数据包大小和数据包