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

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

客户:

#include  #include  #include  #include  #include  #include  #include  #include  #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=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 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  #include  #include  #include  #include  #include  #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 0){ index1 = my_data[i]; myDataBinary[index1] = 1; printf("my data %d = %d\n",index1,myDataBinary[index1]); } } for(int i=0; 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 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; 

}

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

 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 

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

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

尝试这样的事情:

客户:

 #include  #include  #include  #include  #include  #include  #include  #include  #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], ki); if (rc < 0) { closesocket(sockfd); error("ERROR in write"); } i += rc; } closesocket(sockfd); return 0; } 

服务器:

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