Head First C 学习之Client

和服务器用BLAB四部曲(bind()linsten()accept(),开始对话)不同,客户端只需要两步:

1、连接远程端口

2、开始通信

远程端口和IP地址

  • 客户端需要知道远程服务器的IP地址和端口。
  • IP地址很难记忆,一般使用域名。
  • 网路中的数据包只使用数字的IP地址。

创建IP地址套接字

客户端套接字和服务器套接字以相同的方式创建。

#include 
...
int s = socket(PF_INET,SOCK_STREAM,0);
//s是套接字的描述符->互联网套接字
//0是协议号,默认填0就可以。
、、、
if(s == -1)
    error("无法打开套接字");

但是客户端和服务器套处理套接字的方式不同。

struct sockaddr_in si;
si.sin_family = PF_INF;
si.sin_addr.s_addr = int_addr("208.201.239.100");
si.sin_port=htons(80);

connect(s,(struct sockaddr *)&si,sizeof(si));

getaddrinfo()获取域名地址

域名系统(Domain Name System,DNS)

创建域名套接字

为了使用DNS,余姚以另一种方式构建客户端套接字:

#include 
//使用getaddrinfo()函数需要的头文件
...
struct addrinfo *res;
struct addrinfo hints;
memset(&hints,0,sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("www.oreilly.com","80",&hints,&res);
//getaddrinfo()接受字符串格式的端口号。

getaddrinfo()会在堆上创建一种叫名字资源的新数据结构。
给定域名和端口号,就可以得到名字资源。
名字资源把计算机需要的IP地址隐藏起来,大型网址通常有好几个IP地址,代码回从中挑选一个。
可以用名字资源创建套接字了:

int s = socket(res->ai_family,res->ai_socktype,ress->ai_protocol);

连接套接字,因为名字资源在堆上创建,因此要用freeaddrinfo()的函数来清除它。

connect(s,res->ai_addr,res->ai_addrlen);
//res->ai_addr是远程主机
freeaddrinfo(res);

一旦连接到运城端口,就可以用recv()send()函数读写数据了。

你可能感兴趣的:(Head First C 学习之Client)