套接字编程出错并在C中使用htonl(),htons()函数

时间:2011-07-28 17:37:52

标签: c sockets

我正在粘贴下面的客户端和服务器代码。我的程序运行正常,除了我试图在我的src和dest字段中发送一个ipaddress,由于某种原因,即使我发送它为131.199.166.232,它打印为232.166.199.131。但我的其余数据包值以适当的方式打印。我已经使用了memcpy(),所以我觉得它是一个memcpy的东西,在某个地方我做错了,但在Beej的指南中,因为有一个部分@在不同的计算机体系结构中的字节排序.....我没有使用过htonl()所有,也许是因为那个。请指导我,因为我出错了。另外请告诉我发送数据的方式,如何在我的代码中使用htonl()函数....提前感谢。

客户:

         #include <stdio.h>
         #include <stdlib.h>
         #include <string.h>
         #include <math.h>
         #include <sys/types.h>
         #include <sys/socket.h>
         #include <netinet/in.h>
         #include <netdb.h>
         #define MAXPROFILES  2

        int main(int argc, char *argv[])

      {
        int sockfd, portno, n;
        struct sockaddr_in serv_addr;
        struct hostent *server;
        unsigned char buf[1024];
        unsigned int srcAddress = 2193598184;
        unsigned int destAddress = 2193598182;

       struct profile_t
     {
       unsigned char length;
       unsigned char type;
       unsigned char *data;
     };

       typedef struct profile_datagram_t
     {
    unsigned char src[4];
    unsigned char dst[4];
    unsigned char ver;
    unsigned char n;
    struct profile_t profiles[MAXPROFILES];
     } header;


        header outObj;

        int j =0;
        int i =0;
       // for loop for doing the malloc so that we can allocate memory to all profiles
        for(i=0;i<MAXPROFILES;i++){
    outObj.profiles[i].data = malloc(5);
      }


        for(i=3;i>=0;i--){
    outObj.src[i] = (srcAddress >> (i*8)) & 0xFF;
    outObj.dst[i] = (destAddress >> (i*8)) & 0xFF;
    printf("%d",outObj.src[i]);
     }
        outObj.ver = 1;
        outObj.n = 2;

        memcpy(buf,&outObj.src,4);
        memcpy(buf+4,&outObj.dst,4);
        memcpy(buf+8,&outObj.ver,1);
        memcpy(buf+9,&outObj.n,1);


        outObj.profiles[0].length = 5;
        outObj.profiles[0].type = 1;
        outObj.profiles[1].length = 5;
        outObj.profiles[1].type = 2;

        for(i=0;i<MAXPROFILES;i++){
    for(j=0;j<5;j++){
        outObj.profiles[i].data[j] = j+1;
    }
}



        int k = 10;

            // for loop to do memcopy of length,type and data.
        for(i=0;i<MAXPROFILES;i++){
    memcpy(buf+k,&outObj.profiles[0].length,1);
    memcpy(buf+k+1,&outObj.profiles[0].type,1);
    memcpy(buf+k+2,outObj.profiles[0].data,5);
    k +=7;
}


       if (argc < 3) {
       fprintf(stderr,"usage: %s hostname port\n", argv[0]);
       exit(0);
    }
       portno = atoi(argv[2]); //Convert ASCII to integer
       sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor


       if (sockfd < 0)
       error("ERROR DETECTED !!! Problem in opening socket\n");

       server = gethostbyname(argv[1]);
       if (server == NULL) {
       fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
        exit(0);
    }

      bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address

      serv_addr.sin_family = AF_INET;
      bcopy((char *)server->h_addr,
            (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

      serv_addr.sin_port = htons(portno);

      printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);


      if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
      error("ERROR in connection");

          printf("SUCCESS !!! Connection established \n");


       if (write(sockfd, buf, k) < 0)
       {
      error("Write error has occured ");
       }


      return 0;

}

服务器代码:

               #include <stdio.h>
               #include <stdlib.h>
               #include <string.h>
               #include <sys/types.h>
               #include <sys/socket.h>
               #include <netinet/in.h>
               #define MAXPROFILES  2

               int main(int argc, char *argv[])
            {
               int sockfd, newsockfd, portno, clilen;
               struct sockaddr_in serv_addr, cli_addr;
               unsigned char buf[1024];
               int my_data2[10] = {1,3,9,10};
               int my_data[10] = {1,2,3,4,5};
           int myDataBinary[500] = {0};
           int myDataBinary2[500] = {0};
           int recData[500] = {0};
           int index1=0;


           struct profile_t
            {
            unsigned char length;
            unsigned char type;
            unsigned char *data;
            };

                typedef struct profile_datagram_t
           {
            unsigned char src[4];
            unsigned char dst[4];
            unsigned char ver;
            unsigned char n;
           struct profile_t profiles[MAXPROFILES];
            } header;


                header outObj;

            int j =0;
            int i =0;



                if (argc < 2) {
                fprintf(stderr,"usage: %s port_number1",argv[0]);
                exit(1);
             }
                sockfd = socket(AF_INET, SOCK_STREAM, 0);
                if (sockfd < 0)
                error("ERROR DETECTED !!! Problem in opening socket");

                bzero((char *) &serv_addr, sizeof(serv_addr));
                portno = atoi(argv[1]);

                serv_addr.sin_family = AF_INET;
                serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
                serv_addr.sin_port = htons(portno);

                if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
                error("ERROR DETECTED !!! There was a problem in binding");

                listen(sockfd, 10);
                clilen = sizeof(cli_addr);



                 printf("Server listening on port number %d...\n", serv_addr.sin_port);

                 newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

                 if (newsockfd < 0)
             error("ERROR DETECTED !!! the connection request was not accepted");

             int rc = read(newsockfd,buf,100);
             if(rc < 0){
         printf("error");
          }
             else {
            printf("success %d",rc);
          }


          memcpy(&outObj.src,buf+0,4);
          memcpy(&outObj.dst,buf+4,4);
          memcpy(&outObj.ver,buf+8,1);
          memcpy(&outObj.n,buf+9,1);

              printf("\nsrc ip = ");
              for(int i=0;i<4;i++){
           printf("%d ",outObj.src[i]);
           }

              printf("\ndest ip = ");
              for(int i=0;i<4;i++){
             printf("%d ",outObj.src[i]);
            }

             printf("\nversion = %d",outObj.ver);
             printf("\nnumber = %d",outObj.n);

             int k = 10;

             for(i=0;i<outObj.n;i++){
         memcpy(&outObj.profiles[i].length,buf+k,1);
         memcpy(&outObj.profiles[i].type,buf+k+1,1);
         outObj.profiles[i].data = malloc(outObj.profiles[i].length);
         memcpy(outObj.profiles[i].data,buf+k+2,5);
            k +=7;
           }

             for(int i=0;i<outObj.n;i++){
        printf("\nMessage %d :",i+1);
        printf("\nLength : %d",outObj.profiles[i].length);
        printf("\nType : %d",outObj.profiles[i].type);
        for(int j=0;j<5;j++){
            printf("\ndata %d : %d",j,outObj.profiles[i].data[j]);
        }
    }


             for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
          {
         if(my_data[i] > 0){
        index1 = my_data[i];
        myDataBinary[index1] = 1;
        printf("my data %d = %d\n",index1,myDataBinary[index1]);
    }
    }

           for(int i=0; i<sizeof(my_data2)/sizeof(int);i++)
    {
        if(my_data2[i] > 0){
            index1 = my_data2[i];
            myDataBinary2[index1] = 1;
            printf("my data %d = %d\n",index1,myDataBinary2[index1]);
        }
    }


             int sumRecievedData = 0;
             int sumMyData = 0;
             int sumMultpliedData = 0;
float Cov =0;
float sdMyData = 0;
float sdRecievedData =0;
int n = 500;
float rho;

for(int i=0;i<outObj.n;i++){
    index1=0;
    for (int j=0; j<outObj.profiles[i].length;j++) {

        if(outObj.profiles[i].data[j] > 0){
            index1 = outObj.profiles[i].data[j];
            recData[index1] = 1;
            printf("rec data %d = %d\n",index1,recData[index1]);
        }
    }
}

for(int i=0;i<500;i++){
    sumRecievedData += recData[i];
    sumMyData += myDataBinary[i];
    sumMultpliedData += recData[i] * myDataBinary[i];
}
        printf("recSum = %d, mySum = %d, multSum = %d",sumRecievedData,sumMyData,sumMultpliedData);
        Cov = (1.0/(n-1))*(sumMultpliedData - (1.0/n)*sumMyData*sumRecievedData);
        sdMyData = sqrt((1.0/(n-1))*(sumMyData - (1.0/n)*sumMyData*sumMyData));
        sdRecievedData = sqrt((1.0/(n-1))*(sumRecievedData - (1.0/n)*sumRecievedData*sumRecievedData));
        printf("Covariance = %f, Variance 1 = %f, Variance 2 = %f",Cov,sdMyData,sdRecievedData);
        if (sdMyData == 0.0 || sdRecievedData == 0.0){
        rho = 0.0;
        }else{
        rho = Cov/(sdMyData*sdRecievedData);
        }
    printf("Pearson Coefficient = %f",rho);



return 0;

}

2 个答案:

答案 0 :(得分:2)

您需要决定如何发送数据并以此格式转换数据:

if (write(sockfd, buf, k) < 0)

您使用以下任一方法:

htons() host to network short

htonl() host to network long

ntohs() network to host short

ntohl() network to host long

答案 1 :(得分:0)

通常,你应该在结构中使用常规整数而不是字节数组,然后使用hton ...()将这些值放入发送缓冲区时按网络字节顺序放置,然后使用ntoh ... ()在将值复制出接收缓冲区时将值重新置于主机字节顺序。您的代码以主机字节顺序运行。网络传输应使用网络字节顺序。

话虽如此,IPv4地址是一种特殊情况,因为有额外的函数可用于处理IP字符串,它们希望数值只能按网络字节顺序排列。

尝试这样的事情:

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define MAXPROFILES  2

struct profile_t
{
    unsigned char length;
    unsigned char type;
    unsigned char *data;
};

struct profile_datagram_t
{
    unsigned long src;
    unsigned long dst;
    unsigned char ver;
    unsigned char n;
    profile_t profiles[MAXPROFILES];
};

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        fprintf(stderr,"usage: %s hostname port\n", argv[0]);
        exit(0);
    }

    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    unsigned char buf[1024];

    profile_datagram_t outObj;
    int i;
    int j;

    outObj.src = inet_addr("130.191.166.232");
    outObj.dst = inet_addr("130.191.166.230");
    outObj.ver = 1;
    outObj.n = 2;

    memcpy(&buf[0], &outObj.src, 4);
    memcpy(&buf[4], &outObj.dst, 4);
    memcpy(&buf[8], &outObj.ver, 1);
    memcpy(&buf[9], &outObj.n, 1);

    int k = 10;
    for(i = 0; i < MAXPROFILES; ++i)
    {
        outObj.profiles[i].length = 5;
        outObj.profiles[i].type = i+1;
        outObj.profiles[i].data = malloc(5);

        for(j = 0; j < 5; ++j)
        {
            outObj.profiles[i].data[j] = j+1;
        }

        memcpy(&buf[k], &outObj.profiles[i].length, 1);
        memcpy(&buf[k+1], &outObj.profiles[i].type, 1);
        memcpy(&buf[k+2], outObj.profiles[i].data, 5);
        k +=7;
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
    if (sockfd < 0)
        error("ERROR in opening socket\n");

    server = gethostbyname(argv[1]);
    if (server == NULL)
    {
        closesocket(sockfd);
        fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

    portno = atoi(argv[2]); //Convert ASCII to integer
    serv_addr.sin_port = htons(portno);

    printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);

    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    {
        closesocket(sockfd);
        error("ERROR in connect");
    }

    printf("SUCCESS !!! Connection established \n");

    i = 0;
    while (i < k)
    {
        int rc = write(sockfd, &buf[i], k-i);
        if (rc < 0)
        {
            closesocket(sockfd);
            error("ERROR in write");
        }
        i += rc;
    }

    closesocket(sockfd);
    return 0; 
}

服务器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXPROFILES  2

struct profile_t
{
    unsigned char length;
    unsigned char type;
    unsigned char *data;
};

struct profile_datagram_t
{
    unsigned long src;
    unsigned long dst;
    unsigned char ver;
    unsigned char n;
    profile_t profiles[MAXPROFILES];
};

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr, "usage: %s port_number1", argv[0]);
        exit(1);
    }

    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    struct in_addr addr;
    unsigned char buf[1024];
    int buflen;

    profile_datagram_t outObj;

    int i;
    int j;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR in opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR in binding");

    if (listen(sockfd, 10)) < 0)
        error("ERROR in listening");

    printf("Server listening on port number %d...\n", portno);

    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
    closesocket(sockfd);

    if (newsockfd < 0)
        error("a connection request was not accepted");

    buflen = 0;
    while (buflen < 10)
    {
        int rc = read(newsockfd, &buf[buflen], 10-buflen);
        if(rc <= 0)
        {
            closesocket(newsockfd);
            error("ERROR in read");
        }

        buflen += rc;
    }

    memcpy(&outObj.src, &buf[0], 4);
    memcpy(&outObj.dst, &buf[4], 4);
    memcpy(&outObj.ver, &buf[8], 1);
    memcpy(&outObj.n, &buf[9], 1);

    addr.s_addr = outObj.src;
    printf("\nsrc ip = %s", inet_ntoa(&addr));

    addr.s_addr = outObj.dst;
    printf("\ndest ip = %s", inet_ntoa(&addr));

    printf("\nversion = %d", outObj.ver);
    printf("\nnumber = %d", outObj.n);

    for(i = 0; i < outObj.n; ++i)
    {
        buflen = 0;
        while (buflen < 2)
        {
            int rc = read(newsockfd, &buf[buflen], 2-buflen);
            if (rc <= 0)
            {
                closesocket(newsockfd);
                error("ERROR in read");
            }
            buflen += rc;
        }

        memcpy(&outObj.profiles[i].length, &buf[0], 1);
        memcpy(&outObj.profiles[i].type, &buf[1], 1);

        outObj.profiles[i].data = malloc(outObj.profiles[i].length);

        buflen = 0;
        while (buflen < outObj.profiles[i].length)
        {
            int rc = read(newsockfd, &buf[buflen], outObj.profiles[i].length-buflen);
            if (rc <= 0)
            {
                closesocket(newsockfd);
                error("ERROR in read");
            }
            buflen += rc;
        }

        printf("\nMessage %d :",i+1);
        printf("\nLength : %d", outObj.profiles[i].length);
        printf("\nType : %d", outObj.profiles[i].type);
        for(j = 0; j < outObj.profiles[i].length; j)
            printf("\ndata[%d] : %d", j, outObj.profiles[i].data[j]);
    }

    closesocket(newsockfd);

    return 0;

}