socket()函数
项目 | 描述 |
---|---|
头文件 | #include <sys/types.h> #include <sys/socket.h> |
原型 | int socket(int domain, int type, int protocol); |
功能 | 根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源 |
参数 | domain:指定一个通信域;这个选择用于通信的协议系列. type:选择sock的类型 protocol:一般为0(原始套接字时需填充) |
返回值 | 成功时返回文件描述符;失败时返回EOF |
备注 | 原始套接字只能由超级用户创建 |
栗子
#include<sys/types.h>
#include<sys/socket.h>
int sockfd;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
perror("socket");
exit(-1);
}
bind()函数
项目 | 描述 |
---|---|
头文件 | #include <sys/types.h> #include <sys/socket.h> #include<arpa/inet.h> |
原型 | int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen) |
功能 | 绑定本地地址到套接字 |
参数 | sockfd:由socket调用返回的套接字描述字 my_addr:一个指向sockaddr的指针,实际应用中,一般使用指向struct sockaddr_in的指针代替 addrlen:sockaddr结构的长度,一般可用sizeof(struct sockaddr)或sizeof(struct sockaddr_in)代替 |
返回值 | 成功返回0;失败返回EOF |
备注 | 设置端口号时,可以选择大于1024的端口号;如果端口号为0,则表明由系统自动分配端口号 设置IP地址时,如果地址为INADDR_ANY,则表明自动加载本地IP |
struct sockaddr_in结构体详解
man 7 ip可查看具体信息
参数解释
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
//sin_family指代协议簇,
/*协议簇:
AF_UNIX(本机通信)
AF_INET(TCP/IP – IPv4)
AF_INET6(TCP/IP – IPv6)
*/
//sin_port存储端口号(使用网络字节顺序)
//sin_addr存储IP地址,使用in_addr这个数据结构
//s_addr按照网络字节顺序存储IP地址
栗子
struct sockaddr_in my_addr;
int rt;
//调用socket返回sockfd描述符,见socket栗子
my_addr.sin_family = AF_INET; //协议簇
my_addr.sin_port = htons(1500); //服务器端进程使用的端口号,网络字节序
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP地址,网络字节序
bzero(&(my_addr.sin_zero),8);
if((rt = bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))) < 0){
perror("bind");
exit(-1);
}
listen()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> |
原型 | int listen(int sockfd,int backlog); |
功能 | 在bind对应的地址和端口上监听 |
参数 | sockfd:由socket调用返回的套接字描述符 backlog:请求队列大小,一般默认为20 |
返回值 | 成功时返回0;失败返回EOF |
备注 | backlog并不代表服务器端可同时处理的客户端个数,而是向服务器端同时发起连接请求的客户端个数 |
栗子
int BACKLOG = 5;
//socket,bind 省略
if(listen(sockfd,BACKLOG) == -1){
perror("listen");
exit(-1);
}
accept()函数
项目 | 描述 |
---|---|
头文件 | #include<sus/type.h> #include<sys/socket.h> |
原型 | int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen); |
功能 | 接收客户端的连接请求 |
参数 | sockfd:由socket调用返回的套接字描述符 addr与addrlen:用来给客户端的程序填写的,服务器端只要传递对应类型的指针就可以了 |
返回值 | 成功时返回非负整数,代表连接套接字描述符;失败时返回EOF |
栗子
int connfd;
struct sockaddr_in caddr;
socklen_t c_addrlen;
//socket,bind,listen省略
if((connfd = accept(sockfd,(struct sockaddr *)&c_addr,&c_addrlen)) == -1){
perror("accept");
exit(-1);
}
connect()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/types.h> #include<sys/socket.h> |
原型 | int connect(int sockfd,const struct sockaddr *serv_addr,socklen_t addrlen); |
功能 | 客户端向服务器端发起连接请求 |
参数 | sockfd:由socket调用返回的套接字描述符 serv_addr:保存服务器端地址端口等信息,可用struct sockaddr_in形式代替 addrlen:serv_addr的长度,可用sizeof(struct sockaddr_in)代替 |
返回值 | 成功返回0;失败返回EOF |
备注 | 需要事先绑定号服务器端地址等信息 |
栗子
struct sockaddr_in s_addr;
//绑定服务器端地址结构方法见bind栗子
if(connect(sockfd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)) < 0){
perror("connect");
exit(-1);
}
send()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/types.h> #include<sys/socket.h> |
原型 | ssize_t send(int s,const void *buf,size_t len,int flags); |
功能 | 面向连接的套接字发送数据 |
参数 | s:由socket调用返回的套接字描述符 buf:即将发送的数据区域首地址 len:发送的数据区域字节个数 flags:标志位 ----- 0:表明此时send功能和write相同 ----- MSG_DONTROUTE:目标为本地主机,告诉IP协议不查找路由表 |
返回值 | 成功时返回已经成功发送的字节个数;失败时返回EOF |
栗子
char buf[30] = "hello world";
//socket等省略,假设accept返回connfd连接套接字
send(connfd,buf,strlen(buf),0);
sendto()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/types.h> #include<sys/socket.h> |
原型 | ssize_t sendto(int s,const void *buf,size_t len,int flags,const struct sockaddr *to,socklen_t tolen); |
功能 | 面向连接或面向无连接的套接字发送数据 |
参数 | s:由socket调用返回的套接字发送数据 buf:即将发送的数据区域首地址 len:发送的数据区域字节个数 flags:标志位 ----- 0:表明此时send功能和write相同 ----- MSG_DONTROUTE:目标为本地主机,告诉IP协议不查找路由表 to:对方地址信息 tolen:对方地址长度 |
返回值 | 成功时返回已经成功发送的字节个数;失败时返回EOF |
栗子
char buf[30] = "hello world";
struct sockaddr_in toaddr;
int toaddrlen;
//socket等省略,假设accept返回connfd连接套接字
//填充toaddr地址信息方法与bind中相同
toaddrlen = sizeof(toaddr);
sendto(connfd,buf,strlen(buf),0,&toaddr,toaddrlen);
recv()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/types.h> #include<sys/socket.h> |
原型 | ssize_t recv(int s,void *buf,size_t len,int flags); |
功能 | 面向连接的套接字接收数据 |
参数 | s:由socket调用返回的套接字发送数据 buf:将接收的数据所保存的区域首地址 len:将接收的数据字节个数 flags:标志位 ----- 0:表明此时recv功能与read相同 ----- MSG_PEEK:只查看数据,不读出数据,下一次还能读到刚才的数据 ----- MSG_WAITALL:等希望接收的数据字节个数到达时返回,否则阻塞等待,除非遇到以下条件才结束阻塞:读到指定字节数据;读到文件结束符;被信号中断;发生错误 |
返回值 | 成功返回已经成功接收的字节个数;失败返回EOF |
栗子
char buf[30];
//socket等省略,假设accept返回connfd连接套接字
recv(connfd,buf,sizeof(buf)-1,0);
recvfrom()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/types.h> #include<sys/socket.h> |
原型 | ssize_t recvfrom(int s,void *buf,size_t len,int flags,struct sockaddr * from,socklen_t *fromlen); |
功能 | 面向连接或面向无连接的套接字接收数据 |
参数 | s:由socket调用返回的套接字发送数据 buf:将接收的数据所保存的区域首地址 len:将接收的数据字节个数 flags:标志位 ----- 0:表明此时recv功能与read相同 ----- MSG_PEEK:只查看数据,不读出数据,下一次还能读到刚才的数据 ----- MSG_WAITALL:等希望接收的数据字节个数到达时返回,否则阻塞等待,除非遇到以下条件才结束阻塞:读到指定字节数据;读到文件结束符;被信号中断;发生错误 from:对方地址信息 formlen:保存对方地址长度 |
返回值 | 成功返回已经成功接收的字节个数;失败返回EOF |
栗子
char buf[30];
struct sockaddr_in fromaddr;
int fromaddrlen;
//socket等省略,假设accept返回connfd连接套接字
recvfrom(connfd,buf,sizeof(buf)-1,0,&fromaddr,&fromaddrlen);
shutdown()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> |
原型 | int shutdown(int s,int how); |
功能 | 能关闭s所指套接字描述符的单向或双向的连接 |
参数 | s:由socket调用返回的套接字描述符 how:标志位 ----- SHUT_RD:只关闭连接的读 ----- SHUT_WD:只关闭连接的写 ----- SHUT_RDWR:连接的读和写都关闭 |
返回值 | 成功时返回0;失败时返回EOF |
htons()函数
项目 | 描述 |
---|---|
头文件 | #include<netinet/in.h> |
原型 | uint16_t htons(uint16_t hostshort); |
功能 | 主机字节顺序到网络字节顺序的转换,短整型 |
参数 | hostshort:一个16位的短整型数据 |
返回值 | 一个16位的短整型数据,网络字节顺序 |
htonl()函数
项目 | 描述 |
---|---|
头文件 | #include<netinet/in.h> |
原型 | uint32_t htol(uint32_t hostlong); |
功能 | 主机字节顺序到网络字节顺序的转换,长整型 |
参数 | hostlong:一个32位的长整型数据 |
返回值 | 一个32位的长整型数据,网络字节顺序 |
ntohs()函数
项目 | 描述 |
---|---|
头文件 | #include<netinet/in.h> |
原型 | uint16_t ntohs(uint_t16 netshort); |
功能 | 网络字节顺序到主机字节顺序的转换,短整型 |
参数 | netshort:一个16位的短整型数据 |
返回值 | 一个16位的短整型数据,主机字节顺序 |
ntohl()函数
项目 | 描述 |
---|---|
头文件 | #include<netinet/in.h> |
原型 | uint32_t ntohl(uint_t32 netlong); |
功能 | 网络字节顺序到主机字节顺序的转换,长整型 |
参数 | netlong:一个32位的长整型数据 |
返回值 | 一个32位的长整型数据,主机字节顺序 |
inet_addr()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> |
原型 | in_addr_t inet_addr(const char *cp); |
功能 | 将IP地址从点分十进制的字符串形式转换成32位整型形式,网络字节顺序 |
参数 | cp:点分十进制字符串形式的IP地址 |
返回值 | 有效返回32位整型IP地址(网络字节顺序),无效返回EOF |
备注 | 对255.255.255.255认为是无效的 |
inet_pton()函数
项目 | 描述 |
---|---|
头文件 | #include <arpe/inet.h> |
原型 | int inet_pton(int af,const char *src,void *dst); |
功能 | 将IPV4/IPV6的地址转换成网络二进制格式 |
参数 | af:地址协议族(AF_INET或AF_INET6) src:填写点分形式的IP地 dst:存放转换后的结果 |
返回值 | 成功返回1;失败返回EOF |
inet_ntop()函数
项目 | 描述 |
---|---|
头文件 | #include <arpe/inet.h> |
原型 | const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); |
功能 | 将网络二进制格式转换成IPV4/IPV6的地址 |
参数 | af:地址协议族(AF_INET或AF_INET6) src:填写点分形式的IP地 dst:存放转换后的结果 cnt:所指向缓存区dst的大小 |
返回值 | 成功返回指向结构体的指针,失败返回EOF |
inet_network()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> |
原型 | in_addr_t inet_network(const char *cp); |
功能 | 将IP地址从点分十进制的字符串形式转换成32位整型形式,主机字节顺序 |
参数 | cp:点分十进制字符串形式的IP地址 |
返回值 | 有效返回32位整型IP地址(主机字节顺序),无效返回EOF |
inet_aton()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> |
原型 | int inet_aton(const char *cp,struct in_addr *inp); |
功能 | 将IP地址从点分十进制的字符串形式转换成32位整型形式,网络字节顺序 |
参数 | cp:点分十进制字符串形式的IP地址 inp:将转换后的IP地址保存在结构体中 |
返回值 | 如果CP有效则返回非0,无效则返回0; |
inet_ntoa()函数
项目 | 描述 |
---|---|
头文件 | #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> |
原型 | char *inet_ntoa(struct in_addr in); |
功能 | 将IP地址从整型的IP转换为点分十进制的字符串形式 |
参数 | in:结构体in_addr代表IP地址 |
返回值 | 点分十进制形式的字符串首地址,代表IP地址 |
备注 | 字符串保存在静态存储区,因此这个函数不是线程安全的 |
gethostname()函数
项目 | 描述 |
---|---|
头文件 | #include<unistd.h> |
原型 | int gethostname(char *name,size_t len); |
功能 | 获取本地主机名 |
参数 | name:保存获取的主机名 len:可保存主机名最长的长度 |
返回值 | 成功:返回0;失败返回EOF |
gethostbyname()函数
项目 | 描述 |
---|---|
头文件 | #include<netdb.h> |
原型 | struct hostent *gethostbyname(const char *name); |
功能 | 将主机名转换成IP地址 |
参数 | name:主机名 |
返回值 | 指向hostent结构体的指针 |
备注 | 因为返回的指针指向一个静态存储区,所有这不是一个线程安全的函数,相应线程安全的函数为gethostbyname_r |
struct hostent{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
}
#define h_addr h_addr_list[0] //主机的第一个IP地址
gethostbyaddr()函数
项目 | 描述 |
---|---|
头文件 | #include<netdb.h> #include<sys/socket.h> |
原型 | struct hostent *gethostbyaddr(const void *addr,socklen_t len,int type); |
功能 | 将IP地址转换成主机名 |
参数 | addr:指向IP地址,是一个指向地址结构为in_addr的指针 len:地址长度 type:协议簇,如AF_INET |
返回值 | 指向hostent结构体的指针 |