本文主要是介绍inet_ntoa的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
从一段代码开始:
- int test_ntoa()
- {
- struct sockaddr_in recv = {0};
- struct sockaddr_in sa = {0};
- recv.sin_addr.s_addr = -217732928; //192.168.5.243
- sa.sin_addr.s_addr = -939415360; //192.168.5.200
- printf("ip of recv:%s ip of sa:%s\n", inet_ntoa(recv.sin_addr), inet_ntoa(sa.sin_addr));
- printf("ip of recv:%s\n", inet_ntoa(recv.sin_addr));
- printf("ip of sa :%s\n", inet_ntoa(sa.sin_addr));
- return 0;
- }
结果有点诧异:
- ip of recv:192.168.5.243 ip of sa:192.168.5.243
- ip of recv:192.168.5.243
- ip of sa :192.168.1.200
C函数出现这类问题,多半是由于其实现使用了静态内存所知.
google其源码:
- char *
- inet_ntoa (struct in_addr in)
- {
- __libc_once_define (static, once);
- char *buffer;
- unsigned char *bytes;
- /* If we have not yet initialized the buffer do it now. */
- __libc_once (once, init);
- if (static_buf != NULL)
- buffer = static_buf;
- else
- {
- /* We don't use the static buffer and so we have a key. Use it
- to get the thread-specific buffer. */
- buffer = __libc_getspecific (key);
- if (buffer == NULL)
- {
- /* No buffer allocated so far. */
- buffer = malloc (18);
- if (buffer == NULL)
- /* No more memory available. We use the static buffer. */
- buffer = local_buf;
- else
- __libc_setspecific (key, buffer);
- }
- }
- bytes = (unsigned char *) ∈
- __snprintf (buffer, 18, "%d.%d.%d.%d",
- bytes[0], bytes[1], bytes[2], bytes[3]);
- return buffer;
- }
这里使用了静态的缓存buffer,函数把转换后的ip写入缓存buffer,然后返回buffer的首地址值.
看似无奈的选择.glibc里的某些底层函数都使用这类处理方式.
其实也可以选择外部传参的做法解决:
- <pre name="code"class="cpp">char *
- inet_ntoa (struct in_addr in, char* buf, int buflen)
- {
- ... ...
- }
这篇关于inet_ntoa的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!