getaddrinfo

getaddrinfo的一个重要功能, 很方便的构造struct sockaddr_in对象, 把繁琐的构造过程隐藏起来

getaddrinfo兼有gethostbyname和getservbyname等四个函数的功能

能传入ip/port, hostname/port, ip/service, hostname/service的组合

如127.0.0.1/13, www.abc.com/80, 127.0.0.1/daytime

#include <netdb.h>
/* 成功返回0, 出错返回非0 */
int getaddrinfo(const char *hostname,const char *service,
const struct addrinfo *hints, struct addrinfo **result); struct addrinfo{
int ai_flags; /* AI_PASSIVE(用于server的bind), AI_CANONNAME(返回主机名www.abc.com) */
int ai_family; /* AF_INET, AF_INET6, AF_UNSPEC*/
int ai_socktype; /* SOCK_STREAM, SOCK_DGRAM */
int ai_protocol; /* IPPROTO_[IP/IPV4/IPV6/UDP/TCP] */ socklen_t ai_addrlen; /* 下面ai_addr结构的长度 */
char *ai_canonname; /* ai_flags选项返回的主机名 */
struct sockaddr *ai_addr; /* 返回地址结构, 可直接用于connect函数 */
struct addrinfo *ai_next; /* 当查询的主机存在多个地址时通过ai_next来遍历 */
}

hostname和serice就是上面讲的组合

hints是过滤条件, 这些过滤条件放在一个addrinfo的结构里, 通常用前四个成员作为过滤选项

result是过滤的结果, 也是存储在addrinfo结构里, 如果存在多个匹配项, 可通过ai_next来遍历

const char *gai_strerror(int error);

效果同error, 传入错误号返回字符串错误信息

不同的是gai_strerror传入的error是函数的返回值, 而不是全局变量errno

void freeaddrinfo(struct addrinfo *ai);

getaddrinfo的返回值是一个指针, 指向由系统malloc的内存区, 所以不用的时间需要freeaddrinfo

client

启动步骤:

先服务端 ./server13 或者 ./server 0::0 13

然后客户端 ./client 127.0.0.1 13 或者 ./client 0::0 13

#include "unp.h"
#include <netdb.h>
int tcp_connect(const char *host,const char *serv){
int sockfd,n;
struct addrinfo hints,*res,*ressave;
bzero(&hints,sizeof(struct addrinfo));
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
if((n=getaddrinfo(host,serv,&hints,&res)) != 0)
err_quit("tcp_connect error for %s, %s: %s",
host,serv,gai_strerror(n));
ressave=res;
do{
sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
if(sockfd < 0)
continue;
if(connect(sockfd,res->ai_addr,res->ai_addrlen) == 0)
break;
Close(sockfd);
}while((res=res->ai_next) != NULL);
if(res == NULL)
err_quit("tcp_connect error for %s, %s",host,serv);
freeaddrinfo(ressave);
return(sockfd);
} int main(int argc, char *argv[]){
int sockfd,n;
char recvline[MAXLINE+1];
socklen_t len;
struct sockaddr_in addr; if(argc != 3)
err_quit("usage: %s <www/ip> <http/80>",argv[0]); sockfd=tcp_connect(argv[1],argv[2]); len=sizeof(addr);
getpeername(sockfd,(struct sockaddr *)&addr,&len);
printf("connected to %s\n",sock_ntop((struct sockaddr *)&addr,len)); while((n=Read(sockfd,recvline,MAXLINE)) >0){
recvline[n]=0;
Fputs(recvline,stdout);
}
return 0;
}

server

#include "unp.h"
#include <netdb.h>
#include <time.h> int tcp_listen(const char *host,const char *service,socklen_t *addrlenp){
int listenfd,n;
const int on=1;
struct addrinfo hints, *res,*ressave; bzero(&hints,sizeof(struct addrinfo));
hints.ai_flags=AI_PASSIVE;
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM; if((n=getaddrinfo(host,service,&hints,&res)) != 0)
err_quit("tcp_listen error for %s, %s: %s",host,service,gai_strerror(n));
ressave=res; do{
listenfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
if(listenfd < 0)
continue; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
if(bind(listenfd,res->ai_addr,res->ai_addrlen) == 0)
break; Close(listenfd);
}while((res=res->ai_next) != NULL); if(res == NULL)
err_quit("tcp_listen error for %s, %s",host,service); Listen(listenfd,10); if(addrlenp)
*addrlenp=res->ai_addrlen; freeaddrinfo(ressave); return(listenfd);
}
int main(int argc, char *argv[]){
int listenfd,connfd;
socklen_t len;
struct sockaddr_in cliaddr;
char buff[MAXLINE];
time_t ticks; if(argc == 2)
listenfd=tcp_listen(NULL,argv[1],NULL);
else if(argc == 3)
listenfd=tcp_listen(argv[1],argv[2],NULL);
else
err_quit("usage: %s [<host>] <service/port>",argv[0]); for(;;){
len=sizeof(cliaddr);
connfd=Accept(listenfd,(struct sockaddr *)&cliaddr,&len);
printf("connection from %s\n",sock_ntop((struct sockaddr *)&cliaddr,len)); ticks=time(NULL);
snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));
Write(connfd,buff,strlen(buff)); Close(connfd);
}
}

[第四版]用getaddrinfo设置tcp基本连接属性的更多相关文章

  1. {MySQL数据库初识}一 数据库概述 二 MySQL介绍 三 MySQL的下载安装、简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 初识sql语句

    MySQL数据库初识 MySQL数据库 本节目录 一 数据库概述 二 MySQL介绍 三 MySQL的下载安装.简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 ...

  2. 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED

    https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮  F1 4C为CRC高位和低位 ...

  3. 【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)

    最近一直在看的一本书是<Android 应用程序开发权威指南>(第四版),十分推荐.书中讲到了一些用户界面设计的规范,对于初学者我认为十分有必要,在这里码给大家,希望对我们都有用. 在我们 ...

  4. 《Thinking In Java第四版》拾遗

    <Thinking In Java第四版>拾遗 转自我的github(http://katsurakkkk.github.io/2016/05/Thinking-In-Java%E7%AC ...

  5. 在Eclipse下配置算法(第四版)运行环境

    第一步:配置Eclipse运行环境 Eclipse运行环境配置过程是很简单的,用过Eclipse进行java开发或学习的同学应该都很熟悉这个过程了. 配置过程: (1)系统环境:Windows7 64 ...

  6. 《jQuery基础教程(第四版)》学习笔记

    本书代码参考:Learning jQuery Code Listing Browser 原书: jQuery基础教程 目录: 第2章 选择元素 1. 使用$()函数 2. 选择符 3. DOM遍历方法 ...

  7. 《算法》第四版 IDEA 运行环境的搭建

    <算法>第四版 IDEA 运行环境的搭建 新建 模板 小书匠 在搭建之初,我是想不到会出现如此之多的问题.我看了网上的大部分教程,都是基于Eclipse搭建的,还没有使用IDEA搭建的教程 ...

  8. 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1

    <细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...

  9. JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

    switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...

随机推荐

  1. 【caffe-windows】 caffe-master 之 cifar10 超详细

    本教程尽量详细,大多步骤都有图,如果运行出错,请先对照自己的文件是否和图上的一样,包括标点啊,空格啊,斜杠,反斜杠啊之类的小细节. 本例程是在 win10 64位   caffe-master     ...

  2. 学习总结 java 异常

    package com.hanqi.ec; public class Test1 { public static void main(String[] args) { int a = 10 , b = ...

  3. bzoj1003 [ZJOI2006]物流运输

    1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6300  Solved: 2597[Submit][Stat ...

  4. FindResource函数错误代码:1813-找不到映像文件中指定的资源类型 与LoadResource函数错误代码:1812-指定的映像文件不包含资源区域

    HRSRC WINAPI FindResource( _In_opt_  HMODULE hModule, _In_      LPCTSTR lpName, _In_      LPCTSTR lp ...

  5. LoadRunner性能测试指挥中心Controller 《第四篇》

    一.设计场景 1.设计性能测试场景 Controller有两个视图:设计(Design)视图和运行(Run)视图.启动Controller,在Controller主界面里,我们可以看到这两个视图. 1 ...

  6. 【.NET】MD5的用法(对文件、字符串)

    using System;using System.IO;using System.Security.Cryptography;using System.Text;namespace ConsoleA ...

  7. Android IOS WebRTC 音视频开发总结(五七)-- 网络传输上的一种QoS方案

    本文主要介绍一种QoS的解决方案,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help QoS出现的背景: 而当网络发生拥塞的时候,所有的数据流都有 ...

  8. tostring格式化输出

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...

  9. 开发iOS应用程序需要的工具和编程技术

    似乎每个iOS应用开发学习者都是从这篇文章开始写博客的,我也不例外,也从这里写吧,内容雷同,但绝对是原创.因为一直相信,通过自己的理解写出来,是掌握技术一个很好的途径. Xcode苹果最为优秀的集成开 ...

  10. Vue.js学习 Item5 -- 计算属性computed与$watch

    在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作.模板是为了描述视图的结构.在模板中放入太多的逻辑会让模板过重且难以维护.这就是为什么 Vue.js 将绑定表达式限制为一个表达式.如果需 ...