1.创建套接字
int socket(int domain, int type, int protocol)
参数:
domain:设置网络层是用什么协议
- AF_INET IPv4 Internet protocols
- AF_INET6 IPv6 Internet protocols
type:套接字类型
- 流式套接字:默认协议是TCP,不支持UDP的 : SOCK_STREAM
- 数据报套接字:默认协议是UDP,不支持TCP的 :SOCK_DGRAM
protocol: 指定套接字所使用的协议
- 采用套接字默认的类型 0
- IPPROTO_TCP 6
- IPPROTO_UDP 17
返回值:
套接字的操作句柄(文件描述符)
2.绑定地址信息
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
参数:
sockfd:套接字的操作句柄
my_addr:地址信息(IP+PORT)
addrlen:地址信息的长度
返回值:
函数执行成功返回0,否则返回-1, 并设置错误代码
3.监听
int listen(int s, int backlog);
参数:
s:套接字描述符
backlog:已经完成连接正等待应用程序接收的套接字队列的长度,而不是未完成连接的数目.
返回值
函数执行成功时返回0.错误时返回-1,并置相应错误代码
关于backlog
监听状态:
已完成连接队列:三次握手已经完成的连接的集合
未完成连接队列:还处于三次握手当中的tcp连接的集合
backlog可以指定已完成连接的队列大小,如果已完成连接队列已经满了,还有新来的连接,则新来的连接会被丢弃
使用accept 接收新连接,也是从已完成连接队列当中获取创建完成的新连接
4.请求建立连接
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:
sockfd:套接字描述符
addr:服务端地址信息
addrlen:地址信息长度
返回值:
函数执行成功时返回0.错误时返回-1,并置相应错误代码
5.接受请求
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
参数:
s:侦听套接字的操作句柄,从侦听socket接收新的连接请求
addr:客户端地址信息
addrlen:客户端地址信息
返回值:
此调用在发生错误时返回-1.若成功则返回一个非负整数标识这个 连接套接字
服务端建立连接的时候,会重新创建一个socket,将客户端的地址信息拷贝到新创建的socket当中。
原来的socket可称为(侦听socket ) 这样做便可以通过侦听socket 建立多个连接
因为该接口是从已完成连接队列当中获取新的连接,
所以,当已完成连接队列当中没有已经完成的新的连接的时候,该接口如果被调用就会阻塞,直到获取一个新的已完成连接到来。
6.发送数据:
Send, sendto 用于向另一个套接字传递消息. Send 仅仅用于连接套接字,而 sendto可用于任何情况下.
int send(int s, const void *msg, size_t len, int flags);
参数
s:套接字操作句柄
msg:要发送的数据
len :要发送数据的长度
flags:
阻塞发送 0
返回值:
成功时返回发送的字符个数,否则返回-1
int sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
参数:
s:套接字操作句柄
msg:要发送的数据
len :要发送数据的长度
flags:
阻塞发送 0
to : 目标主机的地址信息
tolen:地址信息的长度
返回值:
成功时返回发送的字符个数,否则返回-1
7. 接收数据
recvfrom()调用用于从套接字接收消息,并且不管套接字是否面向连接,都可以用于接收套接字上的数据。
recv()调用通常仅在连接的套接字上使用,
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数:
sockfd:套接字操作句柄,(accept函数的返回值,连接套接字操作句柄)
buf: 存放接收的数据
len :接收数据的最大长度
flags:
阻塞接收 0
探测接收 MSG_PEEK
探测接收:从接收缓冲区当中复制数据到应用层,但是并不删除接收缓冲区当中的数据
相比较之前的阻塞接收而言,阻塞接收也会接收缓冲区复制数据到应用层,但是会删除接收缓冲区当中的数据
返回值:
大于0:接收数据的字节大小
0:对端关闭了连接,即对端调用了close接口
小于0: 接受失败
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
参数:
sockfd:套接字操作句柄
buf:存放接收到的数据
len:接收数据的最大长度
flags:
阻塞接收: 0
src_addr: 源主机的地址信息(发送的数据主机的IP和PORT)
addrlen:地址信息长度
返回值:
这些调用返回接收到的字节数,
当对等方执行有序关闭时,返回值将为0
如果发生错误,则返回-1。 如果发生错误,则将errno设置为指示错误。
8.关闭套接字:
int close(int fd);
close 关闭 一个 文件 描述符 , 使它 不在 指向 任何 文件 和 可以 在 新的 文件 操作 中 被 再次 使用. 任何 与 此 文件
相关联 的 以及 程序 所 拥有 的 锁 , 都 会 被 删除 (忽略 那些 持有 锁 的 文件描述符)
返回值:
close 返回 0 表示 成功 , 或者 -1 表示 有 错误 发生