5.调用/捕获系统函数
这部分我们使用系统的函数来访问网络他们在Unix的头文件里,以及任何支持套接字APP的操作系统(BSD、Windows、Linux、Mac等等)。当你调用他们中间的函数时,内核会自动帮助完成所有工作。
大多数就卡在这些系统函数里。在这儿,因为你可能发现没有可用的man!好,为了帮助顺利适应它,我按照你的程序调用系统函数的顺序来讲解他们。
那么,你需要一些牛奶和饼干,再给你提供一些样例代码。其它的就是你的勇气、高昂的勇气!你会发现原来竟然是如此的快乐!
(请注意,为了代码的简洁,没有包含错误检查。在调用getaddrinfo()函数成功时会返回一个有效的链表(linked list)。有些程序使用原始的地址(properly addressed ---也可译原型的地址)这也可以。)
这个是真正的默默无闻的函数,虽然它有没多参数,但是实际用起来很简单。它对于你建立一个地址结构起到了简化的作用。
一个小小的历史:它曾经是,你会使用所谓的gethostbyname ()的函数做DNS查找。然后你手工加载一些信息给结构SOCKADDR_IN ,并供你调用。
值得庆幸的是,这不再是必要的了。(如果你要编写工作在IPv4和IPv6的代码,使用上边所说的,也是不可取的!)在这现代化的时代,你已经有了getaddrinfo()函数并为你封装好了不少东西,其中包括DNS和服务名称查找,除了你自己填写所需要的结构!
让我们一起来看看!
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
intgetaddrinfo(const char *node, //e.g.
www.example.comor IP
const char *service, //e.g. “http” or port number
const struct addrinfo *hints,
struct addrinfo **res);
在这个函数里有3个输入参数和1个作为返回值的指向链表的指针res。
入参node是要连接的主机名或者IP地址。
下一个入参service是端口号,比如“80”,或者其它特定的服务名称像“http”
、“ftp”、“telnet”、“smtp”等等。
最后,入参hints指向一个你已经填写好了的addrinfo结构。
下面的示例是服务器在你的主机IP地址和端口号3490监听。请注意,他们没有做任何实际的监听或者网络设置;它只是在设置了结构hints并且做了调用。
int status;
struct addrinfohints;
struct addrinfo*servinfo; // will point to theresults
memset(&hints,0, sizeof(hints)); // make sure thestruct is empty
hints.ai_family =AF_UNSPEC; // don’t care IPv4 orIPv6
hints.ai_socktype= SOCK_STREAM; // TCP stream sockets
hints.ai_flags =AI_PASSIVE; // fill in myIP for me
if ((status =getaddreinfo(NULL, “3049”,&hints, &servinfo)) != 0) {
fprintf(stderr, “getaddrinfo error: %s\n”,gai_strerror(status));
exit(1);
}
// servinfo nowpoints to a linked list of 1 or more struct addrinfos
// … do everythinguntil you don’t need servinfo anymore …
// … do everythinguntil you don’t need servinfo anymore …
freeaddrinfo(servinfo);// free the linked-list
请注意:因为ai_family设置为AF_UNSPEC所以达到了与版本无关。你也能设置专为IPv4或者IPv6工作以及其它的地址族。
此外你在这儿看到了AI_PASSIVE标志;他告诉getaddrinfo()复制本机地址给套接字结构。这很好,因为没有硬编码。
译者注:上边的情况通常使用在服务器端!
下边说的就是客户端的情况。
示例:连接到www.example.net的3049端口。
int status;
struct addrinfohints;
struct addrinfo *servinfo; // will point to the results
memset(&hints,0 sizeof(hints)); // make sure the structis empty
hints.ai_family =AF_UNSPEC; // don’t care IPv4 or IPv6
hints.ai_socktype= SOCK_STREAM; // TCP stream sockets
// get ready toconnect
status =getaddrinfo(www.example.net, “3049”, &hints, &servinfo);
// servinfo nowpoints to a linked list of 1 or more struct addrinfos
// etc.
我一直说servinfo是一个可以指向各种地址的指针。我们写一个简单的演示程序来显示不同的地址信息。这个程序在命令行上打印出你指定主机的IP地址。
showip.c
所需头文件列表:
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
流程图
正如您所看到的,代码调用的getaddrinfo()来填写由res指向的链表,然后我们可以遍历列表以及打印在命令行上。
译者注:测试IPv6失败!请读者自行查找国内可用的IPv6站点。
现在我们已经在控制之下,我们将使用getaddrinfo()得到的结果,我们要传递给其他socket函数,终于,建立我们的网络连接!请继续阅读!
分享到:
相关推荐
Beej’s Guide to Network Programming
C程序员套接字编程指南。 它提供了同时支持IPv6和IPv4的简单客户端和服务器的完整示例。
### Beej's Guide to Network Programming Using Internet Sockets #### 知识点一:网络编程基础概念 - **网络编程**:是指开发能够通过网络(如互联网)与其他计算机进行通信的应用程序的技术。 - **互联网套接字...
### Beej's Guide to Network Programming – 使用互联网套接字 #### 一、介绍与受众定位 **《Beej's Guide to Network Programming》**是一部由Brian "Beej" Hall编写的经典网络编程指南,专注于互联网套接字的...
网络编程经典书,学C++的必看,英文原版
《Beej Guide to Network Programming》是一本深受Linux网络编程初学者欢迎的书籍,它以其易懂的语言和实用的示例深入浅出地介绍了网络编程的基础知识。这本书的中文完整版,"Beej Guide to Network Programming简体...
### Beej's Guide to Network Programming – 简体中文版 #### 1. 前言 本指南旨在为那些在网络编程方面遇到挑战的程序员提供一份实用且易于理解的资源。如果你正在寻找一种简单的方式去理解和掌握网络编程的核心...
### 网络编程书籍《Beej’s Guide to Network Programming》知识点解析 #### 一、书籍简介 《Beej’s Guide to Network Programming Using Internet Sockets》是一本由Brian "Beej" Hall编写的关于网络编程的经典...
标题《Beej's Guide to Network Programming.pdf》和描述《网络编程》揭示了本文档所涉及的主要领域为网络编程。网络编程是计算机程序或软件组件之间通过网络进行通信和数据交换的过程。网络编程的核心在于使用套接...
标题《Beej Guide for Network Programming》和描述中提及的《Beej's Guide to Network Programming Using Internet Sockets》表明,该文档是一份详细且易于理解的网络编程指南,尤其专注于使用C语言和Socket进行...
### Beej's Guide to Network Programming Using Internet Sockets #### 知识点概览 - **网络编程基础**:包括socket的概念及其在Linux环境下的应用。 - **数据结构与处理**:涉及网络编程中的数据结构(如`struct ...