socket网络编程知识

1 sockaddr和sockaddr_in

这两个结构体都用来处理网络通信的地址


sockaddr在头文件<sys/socket.h>中定义,它的缺陷是sa_data将目标地址和端口混在了一起,其具体定义如下:

struct sockaddr{
	sa_family_t sin_family;		;地址族
	char sa_data[14];14字节,包括socket中的目标地址和端口信息
}

sockaddr_in在头文件netinet/in.harpa/inet.h中定义,该结构体解决了sockaddr的缺陷,将port和addr分开储存在两个变量中,其定义如下:

struct sockaddr_in{
	sa_family_t      sin_family;		//地址族
	uint16_t         sin_port;			//16位TCP/UDP端口号
	struct in_addr   sin_addr;			//32位IP地址
	char             sin_zero[8];		//不使用

该结构体中提到的另一个结构体in_addr定义如下,它用来存放32位IP地址:

struct in_addr{
	In_addr_t		s_addr;				//32位IPv4地址
}

sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO)。


对比

两者长度一样,都是16个字节,即占用内存的大小是一致的,因此可以互相转化。两者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。

sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。

sockaddr_in是Internet环境下socket的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数。即,sockaddr_in用于socket定义和赋值,sockaddr用于函数参数。


htons()和inet_addr()

htons()的作用是将端口号由主机字节序转换为网络字节序的整数值(host to net)。

inet_addr()的作用是将一个IP字符串转化为一个网络字节序的整数值,用于sockaddr_in.sin_addr.s_addr。

inet_ntoa()的作用是将一个sin_addr结构体输出成IP字符串(network to ascⅡ)。

htonl()作用和htons()一样,不过它针对的是32位的(long),而htons()针对的是16位的(short)。

与htonl()和htons()作用相反的两个函数是ntohl()和ntohs()。

2 socket()函数介绍

函数原型:

int socket(int domain, int type, int protocol);

这个函数建议一个协议族为domain、协议类型为type、协议编号为protocol的套接字文件描述符。如果函数调用成功,会返回一个标识这个套接字的文件描述符,失败的时候返回-1。


domain

这个参数用于设置网络通信的域,函数socket()根据这个参数选择通信协议的族。通信协议族在文件sys/socket.h中定义。

domain的值及含义如下表所示:

名称含义
PF_UNIX, PF_local本地通信
AF_INET, PF_INETIPv4网络协议
PF_INET6IPv6网络协议
PF_IPXIPX-NoveⅡ协议
PF_NETLINK内核用户界面设备
PF_X25ITU-T X25 / ISO-8208协议
PF_AX25Amateur radio AX.25
PF_ATMPVC原始ATM PVC访问
PF_APPLETALKAppletalk
PF_PACKET底层包访问

type

用于设置套接字通信的类型,主要值及对应解释如下:

名称含义
SOCK_STREAMTcp连接,提供序列化的、可靠的、双向连接的字节流。支持带外数据传输
SOCK_DGRAM支持UDP连接(无连接状态的消息)
SOCK_SEQPACKET序列化包,提供一个序列化的、可靠的、双向的基本连接的数据传输通道,数据长度定长。每次调用读系统调用时数据需要将全部数据读出
SOCK_RAWRAW类型,提供原始网络协议访问
SOCK_RDM提供可靠的数据报文,不过可能数据会有乱序
SOCK_PACKET这是一个专用类型,不能呢过在通用程序中使用

注意,并不是所有的协议族都实现了这些协议类型,例如,AF_INET协议族就没有实现SOCK_SEQPACKET协议类型。


protocol

这个参数用于指定某个协议的特定类型,即type类型的某个类型。通常某协议中只有一种特定类型,这样protocol参数仅能设置为0;但是有些协议有多种特定的类型,就需要设置这个参数来选择特定的类型。


errno

函数socket()并不总是执行成功,有可能会出现错误,错误的产生有多种原因,可以通过errno获得:

含义
EACCES没有权限建立指定的domain的type的socket
EAFNOSUPPORT不支持所给的地址类型
EINVAL不支持此协议或者协议不可用
EMFILE进程文件表溢出
ENFILE已经达到系统允许打开的文件数量,打开文件过多
ENOBUFS/ENOMEM内存不足。socket只有到资源足够或者有进程释放内存
EPROTONOSUPPORT指定的协议type在domain中不存在
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值