目录
socket类型
流式套接字(SOCK_STREAM) TCP
提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
数据报套接字(SOCK_DGRAM) UDP
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
原始套接字(SOCK_RAW)
可以对较低层次协议如IP、ICMP直接访问。
socket创建流程
服务器:
1.创建流式套接字(socket())------------------------> 有手机
2.指定本地的网络信息(struct sockaddr_in)----------> 有号码
3.绑定套接字(bind())------------------------------>绑定电话
4.监听套接字(listen())---------------------------->待机
5.链接客户端的请求(accept())---------------------->接电话
6.接收/发送数据(recv()/send())-------------------->通话
7.关闭套接字(close())----------------------------->挂机
客户端:
1.创建流式套接字(socket())----------------------->有手机
2.指定服务器的网络信息(struct sockaddr_in)------->有对方号码
3.请求链接服务器(connect())---------------------->打电话
4.发送/接收数据(send()/recv())------------------->通话
5.关闭套接字(close())--------------------------- >挂机
函数接口
socket
int socket(int domain, int type, int protocol);
//作用:创建一个socket通信描述符
domain:指定通信的域(通信协议)
AF_UNIX, AF_LOCAL 本地通信
AF_INET ipv4
AF_INET6 ipv6
type:指定socket的类型
SOCK_STREAM:流式套接字,接下来我们的通信使用TCP协议
SOCK_DGRAM:数据报套接字,接下来我们的通信使用UDP协议
protocol:填0
返回值:如果成功,返回创建的描述符,如果失败,返回-1
connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
作用:请求连接服务器
参数:
sockfd:上面socket接口得到的描述符
addr:相当于服务器的地址(IP+port)
addrlen:地址的长度,因为前面的地址是可变的,所以要通过参数来协定地址的长度
返回值:
0 -1
sockaddr结构体
//从bind接口的帮助文档中拿到
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
上述地址结构是一个通用结构,我们在用实际协议进行通信的时候,需要转换成相应协议的结构体。
用man 7 ip来查看ipv4对应的结构体
struct sockaddr_in {
sa_family_t sin_family; /* 地址协议族,=socket接口第一个参数 */
in_port_t sin_port; /* 指定端口,端口要用网络字节序(大端) */
struct in_addr sin_addr; /* IP地址 */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
bind
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
作用:绑定服务器地址:IP和端口,相当于对外公开自己的IP和端口,客户端就可以连接了
addr:绑定的IP和端口结构体,注意绑定的是自己的IP和端口
IP:取真实的某个网卡的地址,也可以直接写0.0.0.0
addrlen:地址的大小
listen
int listen(int sockfd, int backlog);
作用:进入监听状态,以便接收客户端的连接
sockfd:上面的服务器描述符
backlog:同时能处理的客户端的连接数量,写个5 10都可以
返回值:0 -1
accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
接收客户端连接,注意,这是一个阻塞接口,如果没有新的连接过来,那么会等待
sockfd:上面的服务器描述符
addr:客户端的地址(来电显示)
addrlen:客户端地址的长度,是入参,传入然后可能会被接口修改
返回值:如果成功,会返回一个非负的整数,代表接收的新的连接的描述符
recv/send
//recv和send是网络的专用接口,比起read和write只是多了一个flags参数,flag一般情况下会取0,代表阻塞接受和发送
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
返回值:
>0:接收的字节数
<0:失败
=0:代表对端退出了
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
close
int close(int fd);
关闭套接字连接
标签:sockaddr,socket,int,流程,struct,接口,接字,addr
From: https://blog.csdn.net/cancannidshyshy/article/details/144029943