UNIX网络编程---套接字编程简介(三)
UNIX网络编程---套接字编程简介
一、概述
从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数。这些都是网络编程的基础。Come on!!!!
二、套接字地址结构
大多数套接字函数都需要一个指向套接字地址结构的指针作为参数。每个协议簇都定义它自己的套接字地址结构。这些机构的名字均以sockaddr_开头,并以对应每个协议簇的唯一后缀结尾。
1) Ipv4套接字地址结构
这是一个很常用的套接字。定义在<netinet/in.h>
struct in_addr{in_addr_t s_addr; //32位 IPV4 address};struct sockaddr_in{uint8_t sin_len; //无符号的8位整数sa_family_t sin_family; //应该也为8位整数In_port_t sin_port; //16位无符号struct in_addr sin_addr; //32位char sin_zero[8];};
从进程到内核传递套接字地址结构的 4 个套接字函数( bind 、 connect 、 sendto 、 sendmsg )都要调用 sockargs 函数,该函数从进程复制套接字地址结构,并显示地把它的 sin_len 字段设置成早先作为参数传递给这 4 个函数的该地址结构的长度。从内核到进程传递套接字地址结构的 5 个套接字函数分别是 accept 、 recvfrom 、 recvmsg 、 getpeername 和 getsockname ,均在返回到进程之前设置 sin_len 字段。
Ipv4地址和TCP或UDP端口号在套接字地址结构中总是以网络字节来存储。
套接字地址结构仅在给定主机上使用:虽然结构中的某些字段用在不同主机之间的通信,但是结构本身并不在主机之间传递。
2) 通用套接字地址结构
在头文件 #include <sys/socket.h>
Struct sockaddr{Uint8_tsa_len;Sa_family_t sa_family;Char sa_data[14];};
其实通用套接字struct sockaddr结构体的大小(16字节)和常用的套接字地址struct sockaddr_in大小一样。
3) Ipv6套接字地址结构
在头文件<netinet/in.h>中。
Struct in6_addr{Unit8_ts6_addr[16]; //128-bit Ipv6 address};#define SIN6_LENStruct sockaddr_in6{Uint8_t sin_len;Sa_family_t sin6_family;In_port_t sin6-port;Uint32_t sin6_flowinfo;Struct in6_addr sin6_addr;Uint32_t sin6_scope_id;}
还有关于新的通用套接字的介绍,这里只要知道几个IP地址不一样即可,同时还有各种套接字结构的对比,IPv4的套接字结构最小为16字节,IPv6的套接字结构最小为28个字节。域套接字的长度可变。
三、值—结果参数
当往一个套接字函数传递一个套接字地址结构时,该结构总是以引用形式来传递,该结构的长度也作为一个参数来传递,不过期传递方式取决于该结构的传递方向,是从进程到内核,还是从内核到进程。
从内核到进程的函数,其中两个参数是指向某个套接字地址结构的指针和指向表示该结构大小的整数变量的指针,比如accept,recvfrom。
把套接字地址结构大小这个参数从一个整数改为指向某个整数变量的指针,原因在于:当函数被调用时,结构大小是一个值,它告诉内核结构的大小,这样内核在写该结果时不至于越界;当函数返回时,结构大小又是一个结构,它告诉进程内核在该结构中究竟存储了多少信息。这种类型的参数称为值-结构参数。
在网络编程中,值-结果参数最常见的例子是所返回套接字地址结构的长度。还有一些值-结果参数
Select函数中间的3个参数
Getsockopt函数的长度参数
使用recvmsg函数时,msghdr结构中的msg_namelen和msg_controllen字段
Ifconf机构中的ifc_len字段
Sysctl函数两个长度参数中的第一个。
一句话概括:
从进程传递给内核的参数是需要让内核知道内核需要读取多少字节
从内核传递给内核的参数是需要让进程知道内核给进程写了多少字节
四、字节排序函数
关注如何在主机字节序和网络字节序之间相互转换
#include <netinet/in.h>Uint16_t htons(uint16_t host16bitvalue);Uint32_t htonl(uint32_t host32bitvalue); // 均返回网络字节序的值Uint16_t ntohs(uint16_t host16bitvalue);Uint32_t htons(uint32_t host32bitvalue);//均返回主机字节序的值
在这些函数的名字中,h代表host,n代表network,s代表short,l代表long.short和使用这些函数时,我们并不关心主机字节序和网络字节序的真实值。
五、字节操作函数
字节处理函数
#include <strings.h>Void bzero(void *dest,size_t nbytes);Void bcopy(const void *src,void *dest,size_t nbytes);Int bcmp(const void *ptrl,const void *ptr2,size_t nbytes); //若相等则为0,否则为非0
在c语言中也有和这些功能一样的函数
#include <string.h>Void *memset(void *dest,int c,size_t len);Void *memcpy(void *dest,const void *src,size_t nbytes);Int memcmp(const void *ptrl,const void *ptr2,sieze_t nbytes);// 若相等则为0,否则为<0或者>0
Memset把目标字节串指定数据的字节置为值c。memcpy类似bcopy,不过两个指针参数的顺序是相反的。
记忆memcpy两个指针参数顺序的方法之一是记着他们是按照与C中的赋值语句相同的顺序从左到右写的 dest=src
Memcpy比较两个任意的字节串,若相同则返回0,否则返回一个非0值,是大于0还是小于0则取决于第一个不等的字节。
六、Inet_aton、inet_addr和inet_ntoa函数
#include <arpr/inet.h>int inet_aton(const char *strptr,struct in_addr *addrptr);//若字符串有效则为1,否则为0in_addr_t inet_addr(const char *strptr); //若字符串有效则为32位二进制网络字节序的Ipv4地址,否则为INADDR_NONEchar *inet_ntoa(struct in_addr inaddr); //指向一个点分十进制数串的指针
前两个函数的功能一样
七、Inet_pton和inet_ntop函数
这两个函数是比较新的,对Ipv4和Ipv6都适用。P代表表示(presentation)n代表数值(numeric)
#include <arpa/inet.h>int inet_pton(int family,const chat *strptr,void *addrptr); //若成功为1,
const char *inet_ntop(int family,const void *addrptr,char*strptr,size_t len);
//若成功则为指向结果的指针,出错为NULL
第一个函数尝试转换由strptr指针所指的字符串,并通过addrptr指针存放二进制结果。若成功返回值为1,否则返回0.
Inet_ntop进行相反的转换,从数值格式(addrptr)转换到表达式(strptr)。len参数是目标存储单元的大小,以免该函数溢出调用者的缓冲区。
由点分十进制转换为数值格式的函数(Ipv4):
inet_aton(const char *strptr,struct in_addr *addrptr);inet_addr(const chat *strptr);inet_pton(int family,const char *strptr,void *addrptr);
上图是地址转换函数小结,可以参考,关于地址转换的函数也就那么几个
由数值格式转换为点分十进制(Ipv4):
char *Inet_ntoa(struct in_addr *addrptr);
inet_ntop(int family,const void *addrptr,char*strptr,size_t len);
其中inet_pton()函数的实现:
Intinet_pton(int family,const char *strptr,viod *addrptr){
If(family==AF_INET){Struct in_addr temp;Memset(&temp,0,sizeof(temp));If(Inet_aton(strptr,&temp)){Memcpy(addrptr,&temp,sizeof(temp));Return (1);}Return 0;}Errno=EAFNOSUPPORT;Return (-1);}Const char *inet_ntop(int family,const void *addrptr,char*strptr,size_t len){Const u_char*p=(const u_char *)addrptr;If(family==AF_INET){Char temp[128];Snprintf(temp,sizeof(temp),”%d.%d.%d.%d”,p[0],p[1],p[2],p[3]);If(strlen(temp)>=len){Errno=ENOSPC;Return (NULL);}Strcpy(strptr,temp);Return strptr;}Errno=EAFNOSUPPORT;ReturnNULL;}
八、Sock_ntop和相关函数
这里的函数都是作者为了更好的利用而自己编写的,不是标准的库函数
九、Readn、writen和readline函数
Size_t readn(int fileds,void *buff,size_t nbytes);
Size_t writen(int fileds,const void *buff,size_t nbytes);
Size_t readline(int fileds,void *buff,size_t maxlen);
其中readn函数的实现如下:
Int readn(int fileds,char *str,size_t n)
{Char *ptr;Int nleft,nread;
Nleft=n;
Ptr=str;While(nleft)
{If((nread=read(filed,ptr,n))<0)
{If(errno==EINTR)Nread=0;ElseReturn -1;
}
Else if(nread==0)
Break;Nlefr-=nread;Ptr+=nread;
}Return (n-left);
}
这里只给出了一个函数的具体实现,这些函数只要知道怎么使用,对于基础的学习来说更加重要
UNIX网络编程---套接字编程简介(三)相关推荐
- 【网络】网络基础套接字编程详解
目录 网络初识 1.网络协议初识 2.网络协议的分层: OSI分层模型--->网络理论模型: TCP/IOP五层模型--->工业中采用的网络模型 为什么要有网络分层? 3.网络数据的封 ...
- C/C++Unix网络编程-套接字编程简介
套接字地址结构 套接字的地址结构可以在两个方向上传播:从进程到内核和从内核到进程. IPV4套接字地址结构 sin_len是长度字段,有的平台上的套接字没有这个东西,因为有外置的sizeof运算符.不 ...
- 网络编程套接字编程-代码实现-复习总结
文章目录 一.客户库例程设计 背景知识 前言知识 addrinfo 结构体 getaddrinfo() freeaddrinfo() socket() connect() close() gai_st ...
- 【Linux】网络基础+UDP网络套接字编程
只做自己喜欢做的事情,不被社会和时代裹挟着前进,是一件很奢侈的事. 文章目录 一. 网络基础 1.局域网和广域网 2.协议初识和网络协议分层(TCP/IP四层模型) 3.MAC地址和IP地址(子网掩码 ...
- python 图形化socket编程_Python黑帽编程2.8 套接字编程
Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...
- Python黑帽编程2.8 套接字编程
Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...
- java套接字编程_Java套接字编程:教程
java套接字编程 本教程是Java套接字编程的简介,从一个简单的客户机-服务器示例开始,该示例演示了Java I / O的基本功能. 将向您介绍原始的java.io软件包和NIO,即Java 1.4 ...
- TCP和UDP套接字编程
一.Socket简单介绍 如果要在应用层调用传输层的服务,进行相关程序的设计,就要涉及到套接字编程.套接字也称之为Socket,本质上它就是利用传输层提供的一系列Api来进行网络应用程序的设计. 网络 ...
- 《UNIX网络编程》读书笔记——第三章 套接字编程简介
第三章 套接字编程简介 一.套接字地址结构 以socket_in命名,定义在<netinet/in.h>头文件中. struct in_addr{ in_addr_t s_addr:} ...
最新文章
- ACMNO.31 C语言-宏求余 输入两个整数,求他们相除的余数。用带参的宏来实现,编程序。
- java logout session_在jsp里做“退出登录”, session.setAttribute(id,null)居然出错。高手救命啊!...
- 【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )
- 29.怎样扩展现有类功能?
- linux查看用户拥有的权限
- 基于Unity的弹幕游戏多人联机尝试
- Linux 问题故障定位,看这一篇就够了
- Zabbix分布式监控(zabbix-proxy)的配置关键点
- 深度学习菜鸟的信仰地︱Supervessel超能云服务器、深度学习环境全配置
- [Docker] 03 AUFS
- html5 牧场游戏,手机QQ首批五款HTML5游戏名单 农场偷菜复活
- STM32F7 I2S接口 WM8978 边播放 边录音
- 一个程序员的成长之路(持续更新)
- Office(Word/Excel/PPT)问题集
- 用 python , opencv 打开网络摄像头读取图像
- BugkuCTF misc 旋转跳跃
- CallStranger UPnP 漏洞曝光,影响数十亿台设备
- 从被遗忘到牛市龙头,一文梳理ETH 2020爆发逻辑
- Android输入汉字得到拼音
- 【微信小程序采坑】wx.canvasToTempFilePath生成图片第一次为全透明(白色)的问题?