开发者

Error in socket programming and use of htonl(),htons() functions in C

I am pasting my client and server code below. My program is running fine, except that i am trying to send an ipaddress in my src and dest field, and for some reason, even though i am sending it as 131.199.166.232, it is printing as 232.166.199.131. But rest of my packet values are printed in a proper way. I have used memcpy(), so I feel its a memcpy thing, which somewhere I did wrong, but in Beej's guide as there is a section @ the byte ordering in different computer architectures.....I have not used htonl() and all, so maybe开发者_JAVA百科 it is because of that.Please guide me as where I am going wrong. Also kindly tell me the way i am sending data, how should the htonl() function can be used in my code....Thanks in advance.

Client:

         #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;

}

Server Code:

               #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;

}


You need to decide how you want to send the data and convert data in that format right before:

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

You use either of following:

htons() host to network short

htonl() host to network long

ntohs() network to host short

ntohl() network to host long


In general, you should use regular integers instead of byte arrays in your structs, then use hton...() to put those values be in network byte order when placing them into send buffers, and then use ntoh...() to put the values back into host byte order when copying them out of receive buffers. Your code operates in host byte order. Network transmissions should use network byte order.

With that said, IPv4 addresses are a special case, because there are extra functions available() for working with IP strings, which expect the numeric values to be in network byte order only.

Try something like this:

Client:

#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; 
}

Server:

#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;

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜