网络编程相关API
1. socket() 创建套接字
2. bind() 绑定本机地址和端口
4. listen() 设置监听套接字
5. accept() 接收TCP连接
6. recv(),read(),recvfrom() 数据接收
7. send(),write(),sendto() 数据发送
8. close(),shutdown()关闭套接字
1. socket() 创建套接字
头文件 #include<sys/types.h>
函数原型 int socket (int domain, int type, intprotocol);
功能:根据type 创建某个类型的 套接字,类似于文件io的open();
参数:intdomain 协议类型 一般使用PF_INET或AF_INET
失败:-1
2. bind() 绑定本机地址和端口
补充知识点:
通用地址结构:
Struct sockaddr
{
u_short sa_family; // 地址族, AF_xxx
char sa_data[14]; // 14字节协议地址
};
Internet协议地址结构:
u_short sin_family; // 地址族, AF_INET,2 bytes
u_short sin_port; // 端口,2 bytes 【填充的时候要转换字节序】
struct in_addr sin_addr; //IPV4地址,4 bytes
char sin_zero[8]; // 8bytes unused,作为填充 不同
};
IPV4地址结构
//internetaddress
structin_addr
in_addr_t s_addr; // u32 network address
in_addr_t 等价于 unsigned int
函数1:u_short htons (u_short short),主机字节序到网络字节序端口号转换函数(博文:TCP/IP网络编程基础知识有介绍)
函数2:in_addr_t inet_addr(const char *strptr);将strptr所指的字符串转换成32位的网络字节序二进制值。例如将ip地址:192.168.1.245->0xc0a801f5
注意:这个函数为什么没有像端口号那样需要一个字节序转换函数,因为这个函数顺便把字节序转换了。
bind()函数
头文件 #include<sys/types.h>
函数原型int bind(int sockfd, const structsockaddr *addr,socklen_t addrlen);
目的: 进程 +ip + port + sockfd 形成一个集合
const struct sockaddr *addr ,addr是指向sockaddr_in结构的指针,包含本机IP地址和端口号
struct sockaddr_in
u_short sin_family; // 地址族, AF_INET
u_shortsin_port; // 端口号
struct in_addrsin_addr; // IPV4地址,4 bytes
socklen_t addrlen: sizeof(struct sockaddr)
举例:
struct sockaddr_in my_addr;
my_addr.sin_port = htons (6666);
my_addr.sin_addr.s_addr =inet_addr(“192.168.1.245”);
addrlen = sizeof(struct sockaddr_in)
bind(socketfd, (struct sockaddr*)(&my_addr), addrlen);
注:struct sockaddr是通用的套接字地址是非常早期的socket中bind中使用的参数,一直被保留下来,而struct sockaddr_in则是internet环境下套接字的地址形式,是现在socket实际使用的参数,二者长度一样,都是16个字节,所以两者可以进行强制转化且达到不丢失数据目的。
3. connect() 建立连接
头文件 #include <sys/types.h>
#include <sys/socket.h>
函数原型 int connect(intsockfd, const struct sockaddr *addr,socklen_t addrlen);
功能: 客户端 主动连接服务器,实际上会和服务器进行3次握手(后面博文会讲)
struct sockaddr *addr 这里填服务器的ip+port ,而自己的端口,os会自动分配,ip地址 os 自动帮我找到
socklen_t addrlen sizeof(struct sockaddr_in)
注:connect()是客户端使用的系统调用
4. listen() 设置监听套接字
头文件 #include <sys/types.h>
#include <sys/socket.h>
函数原型int listen (int sockfd, int backlog);
注:该函数执行完,sockfd就变成了监听套接字,只能用来接收客户端的连接,不能用来收发数据。内核启动线程,专门用于处理客户端连接的,先把客户端放到一个队列中,要向真正和该客户端通信起来,要调用accept函数
5. accept() 接收TCP连接
头文件 #include <sys/types.h>
#include <sys/socket.h>
函数原型int accept(int sockfd, struct sockaddr*addr, socklen_t *addrlen);
功能:从队列中,提取一个客户端,创建新的套接字用于和该客户端真正的通信
struct sockaddr *addr 客户端的ip+port
socklen_t *addrlen struct sockaddr 大小
返回值:成功: 新的套接字,服务器真正和客户端 通信 收发数据,就是通过这个套接字,不再使用监听套接字
失败:-1
6. recv(),read(),recvfrom() 数据接收
7. send(),write(),sendto() 数据发送
8. close(),shutdown()关闭套接字
read()/write()/close()是文件IO中函数,其余函数以后再补充。