UNP学习笔记(第三章:套接字编程简介)
本章开始讲解套接字API。
套接字地址结构
IPv4套接字地址结构
它以sockaddr_in命名,下面给出它的POSIX定义
struct in_addr
{
in_addr_t s_addr;
}; stuct sockaddr_in
{
uint8_t sin_len;
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[];
};
POSIX规范只需要这个结构中的3个字段:sin_family、sin_port和sin_addr。
下图列出了POSIX定义的关于socket编程的数据类型

通用的套接字地址结构
为了解决任意套接字地址结构都可以传递进使用套接字地址的套接字函数中,定义了一个通用的套接字地址结构。
任何套接字地址结构的指针都通过类型强制转换(变成通用套接字地址结构的指针)来做为函数参数。
通用的套接字地址结构如下所示
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[];
};
IPv6套接字地址结构
struct in_addr
{
in_addr_t s_addr;
}; struct sockaddr_in
{
uint8_t sin_len;
sa_family_t sin_family; /* AF_INET6 */
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[];
};
字节排序函数
网络字节序采用大端字节序,而不同主机使用不同的字节序。
下面4个函数用于主机字节序和网络字节序之间的相互转换
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
//均返回:网络字节序的值;
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);
//均返回:主机字节序的值;
h代表host,n代表network,s代表short,l代表long。
字节操纵函数
下面函数用于字节的设置、复制和比较。
#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
void bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
//返回:相等则为0,否则为非0
#include <string.h>
void *memset(void *dest, int c, size_t nbytes);
void *memcpy(void *dest, const void *src, size_t nbytes);
int memcmp(const void *s1, const void *s2, size_t nbytes);
//返回:相等则为0,否则为非0
函数inet_aton、inet_addr和inet_ntoa
这几个函数用于在点分十进制数串(如“206.168.112.96”)于它长度为32位的网络字节序二进制值间转换IPv4地址。
#include <arpa/inet.h>
int_addr_t inet_addr(const char *strptr);
//已被舍弃,使用inet_aton函数代替
int inet_aton(const char *strptr, struct in_addr *addrptr);
//返回:字符串有效返回1,否则为0
char *inet_ntoa(struct in_addr inaddr);
//返回:指向一个点分十进制的字符串的指针
函数inet_pton和inet_ntop
相对于上面的几个函数,这两个函数对于IPv4地址和IPv6地址都适用
#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);
//返回:若成功返回1,输入不是有效表达格式返回0,若出错返回-1
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
//返回:若成功则返回指向结果的指针,出错则为NULL
p代表表达(presentation) n代表数值(numeric)
family参数既可以是AF_INET,也可以是AF_INET6。
inet_pton尝试转换由strptr指针指向的字符串,并通过addrptr指针存放二进制结果。
inet_ntop进行相反的转换,len参数是目标储存单元的大小,以免该函数一处其调用者的缓冲区。对此,<netinet/in.h>头文件中由如下定义:
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
UNP中定义的几个函数
inet_ntop函数的一个基本问题是:要求调用者必须知道这个结构的格式和地址族
我们可以使用自己定义的sock_ntop函数来解决这个问题
#include "unp.h"
char *sock_ntop(const struct sodkaddr *sockaddr, socklen_t addrlen);
该函数内部使用sockaddr指针来确定地址族,然后调用inet_ntop。
同样的,我们为操作套接字地址结构定义了如下几个函数

readn、writen和readline函数
字节流套接字(例如TCP套接字)上read和write函数所表现的行为不同于通常的文件
字节流套接字上调用read或write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态,此时所需的是调用者再次调用read或write函数,以输入或输出剩余的字节。
我们提供一下3个函数是每当我们读或写一个字节流套接字时总要使用的函数
#include "unp.h"
ssize_t readn(int filedes,void *buff,size_t nbytes);
ssize_t writen(int filedes,const void *buff,size_t nbytes);
ssize_t readline(int filedes,void *buff,size_t nbytes);
//返回值:读或写的字节数,若出错则为-1
readn实现代码
#include "unp.h"
ssize_t readn(int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr; ptr = vptr;
nleft = n;
while(nleft > )
{
if((nread = read(fd,ptr,nleft)) < )
{
if(errno == EINTR)
{
nread = ;
}
else
{
return -;
}
}
else if(nread == )
{
break;
}
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}
writen实现代码
#include "unp.h"
ssize_t written(int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while(nlfet > )
{
if((nwritten = writen(fd,ptr,nleft)) <= )
{
if(nwritten < && errno ==EINTR)
{
nwritten =;
}
else
{
return -;
}
} nleft -= nwritten;
ptr += nwritten;
}
return n;
}
readline实现代码
#include "unp.h"
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
ssize_t n,rc;
char c,*ptr; ptr = vptr;
for(n = ; n < maxlen; n++)
{
if( (rc = read(fd, &c)) == )
{
*ptr ++ = c;
if(c == '\n')
break;
}
else if (r c== )
{
*ptr = ;
return (n-);
}else
return (-);
} *ptr = ;
return (n);
}
UNP学习笔记(第三章:套接字编程简介)的更多相关文章
- UNP学习笔记3——基本UDP套接字编程
1 概述 TCP和UDP网络编程存在一些本质的差异,主要是由于传输层的差别:UDP是无连接的不可靠的数据报协议,而TCP是面向连接的字节流协议. 下图是典型的UDP客户端和服务器之间的通信流程.客户不 ...
- UNP学习笔记1——基本TCP套接字编程
1 套接字地址结构 大多数套接字函数都需要一个指向套接字地址结构的指针作为参数.每个协议族都定义了自己的套接字结构.这些套接字的结构以sockaddr_开头,以每个协议族唯一的后缀名结尾. 1.1 I ...
- UNIX网络编程 第3章 套接字编程简介
套接字结构类型和相关的格式转换函数
- 《DOM Scripting》学习笔记-——第三章 DOM
<Dom Scripting>学习笔记 第三章 DOM 本章内容: 1.节点的概念. 2.四个DOM方法:getElementById, getElementsByTagName, get ...
- The Road to learn React书籍学习笔记(第三章)
The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...
- [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设
[HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
- 【Unix网络编程】chapter3套接字编程简介
chapter3套接字编程简介3.1 概述 地址转换函数在地址的文本表达和他们存放在套接字地址结构中的二进制值之间进行转换.多数现存的IPv4代码使用inet_addr和inet_ntoa这两个函数, ...
- 【Unix网络编程】chapter3 套接字编程简介
chapter3套接字编程简介3.1 概述 地址转换函数在地址的文本表达和他们存放在套接字地址结构中的二进制值之间进行转换.多数现存的IPv4代码使用inet_addr和inet_ntoa这两个函数, ...
- UNP学习笔记(第二章:传输层)
本章的焦点是传输层,包括TCP.UDP和SCTP. 绝大多数客户/服务器网络应用使用TCP或UDP.SCTP是一个较新的协议. UDP是一个简单的.不可靠的数据报协议.而TCP是一个复杂.可靠的字节流 ...
随机推荐
- Vim插件YCM的安装
YouCompleteMe(YCM)是一款非常好用的Vim插件,但是很多人安装的时候会出问题(尤其是涉及到C和C++的补全),我安装的时候也遇到了问题,现在解决了,给大家参考: Step1: 通过Vu ...
- 【bzoj3771】Triple FFT+容斥原理
题目描述 樵夫的每一把斧头都有一个价值,不同斧头的价值不同.总损失就是丢掉的斧头价值和. 他想对于每个可能的总损失,计算有几种可能的方案. 注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视 ...
- 如何在 Windows 7 上安装 TeX Live 2018
$\color{red}{\mathsf{UPDATE}}$:见李阿玲在知乎专栏 All about TeXnique 发布的安装教程 关于 TeX Live:http://tug.org/texli ...
- linux系统初始化——启动脚本是如何工作的
启动脚本是如何工作的 Linux 使用的是基于 运行级(run-levels) 概念的称为 SysVinit 的专用启动工具.它在不同的系统上可能是完全不一样的,所以不能认为一个脚本在某个 Linux ...
- 【HDU 2087 剪花布条】
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- EasySlider-最简洁的JQuery滚动插件 可控制滚动
原文发布时间为:2010-05-05 -- 来源于本人的百度文章 [由搬家工具导入] Easy Silder是由Alen Grakalic开发的基于JQuery的滚动插件,它支持以下功能: 1.自动滚 ...
- ubuntu php编译安装配置
安装参考:http://ilanni.blog.51cto.com/526870/1569322/ 加载扩展的一些参数参考:http://java-er.com/blog/nginx-php-fpm/
- Maven 集成Tomcat7插件自动部署
1.配置tomcat-users.xml文件 在tomcat安装目录下找到tomcat-users.xml文件.该文件路径为[tomcat安装根目录]/conf/ 修改文件内容,增加下列内容:(一般配 ...
- LeetCode OJ-- Generate Parentheses *
https://oj.leetcode.com/problems/generate-parentheses/ 输入n产生n个( ,n个 )组成的所有合法的括号组合. 现在纸上画画,找到规律: 1.每一 ...
- webview reload 错误 Error Domain=WebKitErrorDomain Code=102 "Frame load interrupted"
在某个特定的场合先需要对WKWebView进行一次reload,但是直接回走到失败的代理方法中并报如下的错误 Error Domain=WebKitErrorDomain Code=102 " ...