TCP套接字的连接函数图
socket
#include<sys/socket.h> int socket(int domain,int type, int protocol); //成功返回文件描述符,失败返回-1. domain 套接字中使用的协议族信息 type 套接字数据传输类型 protocol 计算机通信使用的协议信息
- 协议族
IP_INET IPv4互联网协议族 IP_INET6 IPv6互联网协议族 PF_LOCAL 本地通信UNIX协议族 PF_PACKET 底层套接字协议族 PF_IPX IPX Novell协议族
- 套接字类型
- 面向连接的套接字(SOCK_STREAM)
1.传输过程中数据不会丢失
2.按序传输数据
3.传输的数据不存在数据边界 - 面向消息的套接字(SOCK_DGRAM)
1.强调快速传输并非传输顺序
2.传输的数据有可能丢失也有可能损毁
3.传输的数据有数据边界
4.限制每次传输的数据大小
- 面向连接的套接字(SOCK_STREAM)
- 协议信息
当数据传输方式相同,协议不同时,就要指明第三个协议信息。
在IP_INET中,SOCK_STREAM 对应的是 IPPROTO_TCP, SOCK_DGRAM 对应的是 IPPROTO_UDP
bind
#include<sys/socket.h> int bind(int sockfd,sockaddr *myaddr,socklen_t addrlen); //返回成功是0,失败返回-1 sockfd //套接字的文件描述符 myaddr //指向特定协议的结构 addrlen // sockaddr 字节长度 bind 函数主要用于分配IP地址和端口号,进行绑定。
listen
#include<sys/socket.h> int listen(int sockfd,int backlog); //返回成功是0,否则是-1 sockfd //绑定后的套接字描述符 backlog //设置请求排队的最大长度。 //当由多个客户端请求和服务器连接时,该参数表示可以接收的排队长度 listen 函数 转化为可接受请求状态
accept
#include<sys/socket.h> int accept(int sockfd,struct sockaddr *clien_addr,socklen_t *addrlen); // 返回成功是一个全新的文件描述符代表与客户端建立连接,否则是-1 sockfd //监听后的文件描述符 clien_addr //客户端套接字地址结构指针 addrlen //客户端套接字长度 accept 仅被 tcp 服务器调用。它从已完成连接的队列头返回下一个已完成的连接, 若已完成连接的队列为空,则进入睡眠状态。
connect
#include<sys/socket.h> int connect(int sockfd,struct sockaddr *serv_addr,socklen_t addrlen); //返回成功是0否则是-1 sockfd //文件描述符 serv_addr //指向服务端的地址结构指针 addrlen // 服务端套接字长度 connect函数 tcp 客户端通过 connect 函数来建立一个与 tcp 服务器的连接
linux 下 文件操作
int open(const char *path,int flag); //成功返回文件描述符,失败返回-1 path //文件的字符串地址 flag //文件打开模式信息 O_CREAT //必要时创建文件 O_TRUNC //删除全部现有数据 O_APPEND //维持现有数据保存到其后面 O_RDONLY //只读打开 O_WRONLY //只写打开 O_RDWR //读写打开 int close(int fd);//关闭文件 //成功返回0,失败返回-1 ssize_t write(int fd,const void *buf ,size_t nbytes); //成功返回写入的字节数,失败返回-1 fd //文件描述符 buf //传输数据的缓冲地址值 nbytes //传输数据的字节数 ssize_t read(int fd,const void *buf,size_t nbytes); //成功返回接受的字节数(遇到文件结尾返回0),否则-1 fd //接受对象的文件描述符 buf //要保存接受数据的缓冲区地址 nbytes //要接受数据的最大字节数
地址的结构体
struct sockaddr_in{ sa_family_t sin_family; //地址族 , AF_INET ,AF_INET6,AF_LOCAL. uint16_t sin_port; //16位 TCP/UDP 端口号 ,以网络字节序保存。 struct in_addr sin_addr; //32位IP地址 char sin_zero[8]; //不使用 }; struct in_addr{ In_addr_t s_addr; //32位IPv4地址 }; struct sockaddr{ sa_family_t sin_family; //地址族 char sa_data[14]; // 地址信息 }; #inlcude<arpa/inet.h> in_addrt_t inet_addr(const char *string); //将IP地址转化为32为大端序整数型值。 失败返回INADDR_NONE //INADDR_ANY 自动获取运行服务器的计算机IP地址值。 int inet_aton(const char *string,struct in_addr *addr); //成功返回1,失败返回0, 功能和inet_addr 一样,传入in_addr 结构体变量地址值,直接写入。
字节序转换
比如大端序系统向小端序系统传输数据时,会发生错误,所以要转换。
unsigned short htons(unsigned short); unsigned short ntons(unsigned short); unsigned short htonl(unsigned short); unsigned short ntonl(unsigned short); htonl 表示 host to network long ,用于将主机 unsigned int 型数据转换成网络字节顺序; htons 表示 host to network short ,用于将主机 unsigned short 型数据转换成网络字节顺序; ntohl、ntohs 的功能分别与 htonl、htons 相反。
网络地址结构初始化
- 创建服务器端套接字时需要IP地址的原因
基于UDP的数据I/O函数
写地址并传输数据
接收UDP数据的函数
半关闭
- shutdown函数
域名函数
- 利用域名获取IP地址
- 利用IP地址获取域名