在C中通过套接字传输整数

在C中通过套接字传递int的适当方法是什么?
到目前为止我所做的是:

 int n = 4; int tmp = htonl(n); write(socket, &tmp, sizeof(tmp)); 

 int tmp,n; read(socket, &tmp, sizeof(tmp)); n = ntohl(tmp); 

但是,收到的整数有时为0.并非总是如此,但我要说5次中的2次。 它永远不会是其他价值,总是为什么?为什么?

更新:读取的返回值为-1,错误为:

 Resource temporarily unavailable 

首先, sizeof(int)可能在您的发送方和接收方计算机上有所不同。 所以我建议你使用stdint.h int32_t东西。

此外,不保证read(..,..,sizeof(int))将读取完全sizeof(int)字节 – 它什么都不读,或者它可以读取更少的字节。 所以,正确的变体将是更像这样的东西:

 int send_int(int num, int fd) { int32_t conv = htonl(num); char *data = (char*)&conv; int left = sizeof(conv); int rc; do { rc = write(fd, data, left); if (rc < 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { // use select() or epoll() to wait for the socket to be writable again } else if (errno != EINTR) { return -1; } } else { data += rc; left -= rc; } } while (left > 0); return 0; } int receive_int(int *num, int fd) { int32_t ret; char *data = (char*)&ret; int left = sizeof(ret); int rc; do { rc = read(fd, data, left); if (rc <= 0) { /* instead of ret */ if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { // use select() or epoll() to wait for the socket to be readable again } else if (errno != EINTR) { return -1; } } else { data += rc; left -= rc; } } while (left > 0); *num = ntohl(ret); return 0; } 

这应该没有任何问题,试试这个:

在发件人(服务器)端:

 int number_to_send = 10000; // Put your value int converted_number = htonl(number_to_send); // Write the number to the opened socket write(client_socket, &converted_number, sizeof(converted_number)); 

在接收方(客户端)方面:

 int received_int = 0; return_status = read(client_socket, &received_int, sizeof(received_int)); if (return_status > 0) { fprintf(stdout, "Received int = %d\n", ntohl(received_int)); } else { // Handling erros here } 

希望这会有所帮助。

既然没有人提到过sprintf

你可以使用它将任何变量转换为char*并发送

 if(strcmp(buf,"movUP") == 0) { char* msg = calloc(1, 20); pos.y += 0.0001f; sprintf(msg,"NEW::POS::Y=%.4f", pos.y); sendto(master, msg, 20, 0, (struct sockaddr*)&client, addrlen); } 

测试

 movUP NEW::POS::Y=0.0001 movUP NEW::POS::Y=0.0002 movUP NEW::POS::Y=0.0003 movUP NEW::POS::Y=0.0004 

使用%d表示整数, %f表示浮点数

转换回整数,请使用atoi(char*)
转换回浮点数,使用atof(char*)

在转换之前,一定要使用strstr()来获取浮点值,从"0"

  float myPos; // floating variable that stores Object's Position in the World ... .... memset(buf, 0, MAXBUFFER); // clears the previous buffer recvfrom(master, buf, MAXBUFFER, 0, (struct sockaddr*)&server, &addrlen); char* newY = strstr(buf, "0");// NEW::POS::Y=0.0001 --->> 0.000100 myPos = atof(newY); // new object's position by the server printf("My New Position is %.4f\n", myPos); // Out: My New Position is 0.0011 -> 0.0012 -> 0.0013 -> 0.0014. 

对于整数( 不是位置),你可以使用相同的技术,只需将其相乘即可

 float f = 0.000002f; // that is supposed to be 2 integer value int i = (int)(f*1000000); // now, i = 2 

以上方法完全安全

如果你想要一个更稳定的转换,你可以使用strncpymemcpy并从给定索引开始剪切字符串,假设你已经知道传入的缓冲区,但在我个人看来,我并不是真的推荐它,特别是在像这样的无连接套接字中,大量的计算和调用缓冲区长度,如果你不完全清楚自己在做什么,有时候不容易调试。

注1 :当您等待服务器移动 / 位置命令或任何数量变量时,如果您计划使用一种方法,请注意不要缓冲区中包含

注意2 :您可以发送整数浮点数转换它反之亦然,无需剪切乘以它。

可能新的游戏网络开发人员发现这个答案也很有用,因为除了使用UDP sendto(),recvfrom()的char*之外我们无法发送或接收。