linux socket函数说明
常用socket函数socket 函数。 常用 Berkeley Sockets API 一览表函数名称函数简单描述附加说明
socket创造某种类型的套接字
bind将一个 socket绑定一个ip与端口的二元组上
listen将一个 socket 变为侦听状态
connect试图建立一个 TCP 连接一般用于客户端
accept尝试接收一个连接一般用于服务端
send通过一个socket发送数据
recv通过一个socket收取数据
select判断一组socket上的读事件
gethostbyname通过域名获取机器地址
close关闭一个套接字,回收该 socket 对应的资源Windows 系统中对应的是 closesocket
shutdown关闭 socket 收或发通道
setsockopt设置一个套接字选项
getsockopt获取一个套接字选项
socketsocket()函数的原型如下,这个函数建立一个协议族为domain、协议类型为type、协议编号为protocol的套接字文件描述符。如果函数调用成功,会返回一个标识这个套接字的文件描述符,失败的时候返回-1。#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int socket(int domain, int type, int protocol);
[*]domain
函数socket()的参数domain用于设置网络通信的域,函数socket()根据这个参数选择通信协议的族。通信协议族在文件sys/socket.h中定义。
名称含义名称含义
PF_UNIX PF_LOCAL本地通信PF_X25ITU-T X25 / ISO-8208协议
AF_INET,PF_INETIPv4 Internet协议PF_AX25Amateur radio AX.25
PF_INET6IPv6 Internet协议PF_ATMPVC原始ATM PVC访问
PF_IPXIPX-Novell协议PF_APPLETALKAppletalk
PF_NETLINK内核用户界面设备PF_PACKET底层包访问
[*]type
type 函数socket()的参数type用于设置套接字通信的类型,主要有SOCKET_STREAM(流式套接字)、SOCK——DGRAM(数据包套接字)等。
名称含义
SOCK_STREAMTcp连接,提供序列化的、可靠的、双向连接的字节流。支持带外数据传输
SOCK_DGRAM支持UDP连接(无连接状态的消息)
SOCK_SEQPACKET序列化包,提供一个序列化的、可靠的、双向的基本连接的数据传输通道,数据长度定常。每次调用读系统调用时数据需要将全部数据读出
SOCK_RAWRAW类型,提供原始网络协议访问
SOCK_RDM提供可靠的数据报文,不过可能数据会有乱序
并不是所有的协议族都实现了这些协议类型,例如,AF_INET协议族就没有实现SOCK_SEQPACKET协议类型。
[*]protocol
函数socket()的第3个参数protocol用于制定某个协议的特定类型,即type类型中的某个类型。通常某协议中只有一种特定类型,这样protocol参数仅能设置为0;但是有些协议有多种特定的类型,就需要设置这个参数来选择特定的类型。
[*]errno
函数socket()并不总是执行成功,有可能会出现错误,错误的产生有多种原因,可以通过errno获得:
值含义
EACCES没有权限建立制定的domain的type的socket
EAFNOSUPPORT不支持所给的地址类型
EINVAL不支持此协议或者协议不可用
EMFILE进程文件表溢出
ENFILE已经达到系统允许打开的文件数量,打开文件过多
ENOBUFS/ENOMEM内存不足。socket只有到资源足够或者有进程释放内存
EPROTONOSUPPORT制定的协议type在domain中不存在
比如我们建立一个流式套接字可以这样:int sock = socket(AF_INET, SOCK_STREAM, 0);bind在套接口中,一个套接字只是用户程序与内核交互信息的枢纽,它自身没有太多的信息,也没有网络协议地址和 端口号等信息,在进行网络通信的时候,必须把一个套接字与一个地址相关联,这个过程就是地址绑定的过程。许多时候内核会我们自动绑定一个地址,然而有时用 户可能需要自己来完成这个绑定的过程,以满足实际应用的需要,最典型的情况是一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接。这个事由 bind的函数完成。int bind( int sockfd, struct sockaddr* addr, socklen_t addrlen)
[*]sockfd 就是我们调用socket函数后创建的socket 句柄或者称文件描述符号。
[*]addr addr是指向一个结构为sockaddr参数的指针,sockaddr中包含了地址、端口和IP地址的信息。在进行地址绑定的时候,需要弦将地址结构中的IP地址、端口、类型等结构struct sockaddr中的域进行设置之后才能进行绑定,这样进行绑定后才能将套接字文件描述符与地址等接合在一起。
由于历史原因,我们前后有两个地址结构: struct sockaddr 该结构定义如下:struct sockaddr { uint8_t sa_len; unsigned short sa_family; /* 地址家族, AF_xxx */ char sa_data[14]; /*14字节协议地址*/ };其实这个结构逐渐被舍弃,但是也还是因为历史原因,在很多的函数,比如connect、bind等还是用这个作为声明,实际上现在用的是第二个结构,我们需要把第二个结构强转成sockaddr。 struct sockaddr_in 其定义如下:struct sockaddr_in { uint8_t sa_len; /* 结构体长度*/ short int sin_family; /* 通信类型 */ unsigned short int sin_port; /* 端口 */ struct in_addr sin_addr; /* Internet 地址 */ unsigned char sin_zero[8]; /* 未使用的*/ };struct in_addr { //sin_addr的结构体类型in_addr 原型 unsigned long s_addr; /*存4字节的 IP 地址(使用网络字节顺序)。*/ }; 在使用的时候我们必须指定通信类型,也必须把端口号和地址转换成网络序的字节序
[*]addrlen addr结构的长度,可以设置成sizeof(struct sockaddr)。使用sizeof(struct sockaddr)来设置套接字的类型和其对已ing的结构。
bind()函数的返回值为0时表示绑定成功,-1表示绑定失败,errno的错误值如表1所示。
值含义备注
EADDRINUSE给定地址已经使用
EBADFsockfd不合法
EINVALsockfd已经绑定到其他地址
ENOTSOCKsockfd是一个文件描述符,不是socket描述符
EACCES地址被保护,用户的权限不足
EADDRNOTAVAIL接口不存在或者绑定地址不是本地UNIX协议族,AF_UNIX
EFAULTmy_addr指针超出用户空间UNIX协议族,AF_UNIX
EINVAL地址长度错误,或者socket不是AF_UNIX族UNIX协议族,AF_UNIX
ELOOP解析my_addr时符号链接过多UNIX协议族,AF_UNIX
ENAMETOOLONGmy_addr过长UNIX协议族,AF_UNIX
ENOENT文件不存在UNIX协议族,AF_UNIX
ENOMEN内存内核不足UNIX协议族,AF_UNIX
ENOTDIR不是目录UNIX协议族,AF_UNIX
收集了一下,希望对大家有些帮助。
页:
[1]

