inet_ntoa在64位机器上出错

本文介绍了inet_ntoa及inet_ntop函数的用法,重点解释了这两个函数如何将网络地址结构转换为字符串形式的IP地址。针对64位系统中使用inet_ntoa出现的问题提供了解决方案,并推荐使用更灵活的inet_ntop函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

inet_ntoa用法如下:

char *inet_ntoa(struct in_addr in);
就是将struct in_addr结构转换为IP地址的形式,struct in_addr这个结构应该不陌生吧,它的定义如下:


struct in_addr{
       unsigned long s_addr;
}
struct sockaddr_in {
       short int sin_family;
       unsigned short int sin_port; 
       struct in_addr sin_addr;
       unsigned char sin_zero[8];
};

在服务器端使用accept函数之后,会得到客户端连接的struct sockaddr结构,然后将其转换成struct sockaddr_in结构,此时可以在服务器端得到客户端连接的IP和端口数据。

这时用这个函数有一个问题是:如果在64位的机器上,使用

char* tmp = inet_ntoa(sin->sin_addr);
之后,对tmp进行操作,会出现断错误,但在32位机器上没有问题,原因是64位时inet_ntoa返回值是一个整型。

在网上找的两种解决办法:

  1. 在使用的文件中,引用#include <arpa/inet.h>头文件。
  2. 直接使用inet_ntop函数。

inet_ntop的说明如下:

NAME
       inet_ntop - Parse network address structures

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       #include <arpa/inet.h>

       const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t cnt);

DESCRIPTION
       This  function converts the network address structure src in the af address family into a char-
       acter string, which is copied to a character buffer dst, which is cnt bytes long.

       inet_ntop(3)  extends  the  inet_ntoa(3)  function  to  support  multiple   address   families,
       inet_ntoa(3)  is  now  considered  to  be  deprecated  in favor of inet_ntop(3).  The following
       address families are currently supported:

       AF_INET
              src points to a struct in_addr (network byte order format) which is converted to an IPv4
              network address in the dotted-quad format, "ddd.ddd.ddd.ddd".  The buffer dst must be at
              least INET_ADDRSTRLEN bytes long.

       AF_INET6
              src points to a struct in6_addr (network byte order format) which is converted to a rep-
              resentation of this address in the most appropriate IPv6 network address format for this
              address.  The buffer dst must be at least INET6_ADDRSTRLEN bytes long.

RETURN VALUE
       inet_ntop() returns a non-null pointer to dst.  NULL is returned if there was  an  error,  with
       errno set to EAFNOSUPPORT if af was not set to a valid address family, or to ENOSPC if the con-
       verted address string would exceed the size of dst given by the cnt argument.

CONFORMING TO
       POSIX.1-2001.  Note that RFC 2553 defines a prototype where the last parameter cnt is  of  type
       size_t.  Many systems follow RFC 2553.  Glibc 2.0 and 2.1 have size_t, but 2.2 has socklen_t.


任务要求: 实现简单的 Socket 通信: 两台 PC 间使用 TCP 通信 客户端和服务器之间可以互相发送消息,收到之后在终端上打印出来 server.c:/* Copyright© 2025 Shenzhen TP-LINK Technologies Co.Ltd. * file server.c brief TCP server implementation for socket communication author [Your Name] version 1.0.1 date 2025-07-31 history \arg 1.0.1, 2025-07-31, [Your Name], Create the file. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> // /* DEFINES */ // #define PORT 8080 // Default port number #define BUFFER_SIZE 1024 // Communication buffer size #define MAX_PENDING_CONN 5 // Maximum pending connections #define SERVER_TERM_CMD “shutdown” // Server shutdown command // /* TYPES */ // // /* EXTERN_PROTOTYPES */ // // /* LOCAL_PROTOTYPES */ // // /* VARIABLES */ // // /* LOCAL_FUNCTIONS */ // // /* PUBLIC_FUNCTIONS */ // // /* GLOBAL_FUNCTIONS */ // /* Function: main Purpose: Entry point for TCP server application Parameters: None Return value: 0 on successful execution, non-zero otherwise. Notes: Listens for client connections and handles bidirectional communication */ int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; // Create TCP socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // Configure server address address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; // Accept any IP address.sin_port = htons(PORT); // Listen port // Bind socket to address if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); close(server_fd); exit(EXIT_FAILURE); } // Start listening if (listen(server_fd, MAX_PENDING_CONN) < 0) { perror("Listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Server listening on port %d\n", PORT); // Accept client connection if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("Accept failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Client connected from %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port)); // Communication loop while (1) { // Receive client message memset(buffer, 0, BUFFER_SIZE); ssize_t valread = recv(new_socket, buffer, BUFFER_SIZE - 1, 0); if (valread <= 0) { if (valread == 0) { printf("Client disconnected\n"); } else { perror("Receive error"); } break; } printf("Client: %s\n", buffer); // Check for shutdown command if (strcmp(buffer, SERVER_TERM_CMD) == 0) { printf("Received shutdown command\n"); break; } // Send response to client printf("Server: "); if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) { perror("Input error"); break; } buffer[strcspn(buffer, "\n")] = 0; // Remove newline if (send(new_socket, buffer, strlen(buffer), 0) < 0) { perror("Send failed"); break; } } close(new_socket); close(server_fd); printf("Server shutdown\n"); return 0; } client.c:/* Copyright© 2025 Shenzhen TP-LINK Technologies Co.Ltd. * file client.c brief TCP client implementation for socket communication author [Your Name] version 1.0.1 date 2025-07-31 history \arg 1.0.1, 2025-07-31, [Your Name], Create the file. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // /* DEFINES */ // #define PORT 8080 // Default port number #define SERVER_IP “127.0.0.1” // Loopback address #define BUFFER_SIZE 1024 // Communication buffer size #define MAX_CONN_ATTEMPTS 5 // Maximum connection attempts #define CONN_RETRY_DELAY 2 // Retry delay in seconds // /* TYPES */ // // /* EXTERN_PROTOTYPES */ // // /* LOCAL_PROTOTYPES */ // // /* VARIABLES */ // // /* LOCAL_FUNCTIONS */ // // /* PUBLIC_FUNCTIONS */ // // /* GLOBAL_FUNCTIONS */ // /* Function: main Purpose: Entry point for TCP client application Parameters: None Return value: 0 on successful execution, non-zero otherwise. Notes: Establishes connection to server and handles bidirectional communication */ int main() { int sock = 0; struct sockaddr_in serv_addr; char buffer[BUFFER_SIZE] = {0}; int conn_attempts = 0; // Create TCP socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); } // Configure server address structure serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Convert IP address to binary format if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { perror("Invalid address format"); close(sock); exit(EXIT_FAILURE); } // Attempt connection with retry logic while (conn_attempts < MAX_CONN_ATTEMPTS) { if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection attempt failed"); conn_attempts++; sleep(CONN_RETRY_DELAY); } else { break; } } if (conn_attempts >= MAX_CONN_ATTEMPTS) { fprintf(stderr, "Failed to connect after %d attempts\n", MAX_CONN_ATTEMPTS); close(sock); exit(EXIT_FAILURE); } printf("Connected to server at %s:%d\n", SERVER_IP, PORT); // Communication loop while (1) { // Send message to server printf("Client: "); if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) { perror("Input error"); break; } buffer[strcspn(buffer, "\n")] = 0; // Remove newline if (send(sock, buffer, strlen(buffer), 0) < 0) { perror("Send failed"); break; } // Check for exit command if (strcmp(buffer, "exit") == 0) { printf("Terminating connection\n"); break; } // Receive server response memset(buffer, 0, BUFFER_SIZE); ssize_t valread = recv(sock, buffer, BUFFER_SIZE - 1, 0); if (valread <= 0) { if (valread == 0) { printf("Server disconnected\n"); } else { perror("Receive error"); } break; } printf("Server: %s\n", buffer); } close(sock); return 0; } ——分析下代码有没有问题,需不需要makefile文件,怎么运行这两个代码文件实现通信,不用修改代码,在程序窗口把代码打印出来方便我复制
最新发布
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值