Linux网络:TCP和UDP中的发送和接收函数/send()/sendto()/recv()/recvfrom

目录

一、TCP

1.1send()

1.2recv()

 二、UDP

2.1sendto()

2.2recvfrom()


不管是TCP还是UDP,其都包含同样的头文件

#include <sys/types.h>

#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

                          const struct sockaddr *dest_addr, socklen_t addrlen);

 #include <sys/types.h>
 #include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                           struct sockaddr *src_addr, socklen_t *addrlen);

一、TCP

1.1send()

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

功能:不论是客户还是服务器的应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。 

sockfd:指定发送端套接字描述符;

buf:存放应用程序要发送数据的缓冲区;

len:实际要发送的数据的字节数;

flags:一般置为0。

同步Socket的send函数的执行流程,当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度(因为待发送数据是要copy到套接字s的发送缓冲区的,注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里):

1.如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;

2.如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len:

  (i)如果len大于剩余空间大小send就一直等待协议把s的发送缓冲中的数据发送完;

  (ii)如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里。

3.如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。

注意:send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回 SOCKET_ERROR)。

1.2recv()

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

功能:不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

sockfd:指定接收端套接字描述符;

buf:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

len:指明buf的长度;

flags:一般置为0。

同步Socket的recv函数的执行流程:当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,

如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR;

如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直 等待,直到协议把数据接收完毕;

当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数;

如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。

 二、UDP

2.1sendto()

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

                          const struct sockaddr *dest_addr, socklen_t addrlen);

sendto(),是把UDP数据报发给指定地址;

\sockfd: socket描述符。

\buf: UDP数据报缓存地址。

\len: UDP数据报长度。

\flags: 该参数一般为0。

\dest_addr: sendto()函数参数,struct sockaddr类型,一般在使用时我们的类型是struct sockaddr_in类型,这时需要强制类型转换一下

\addrlen: addr(三种类型)长度,一般为:sizeof(struct sockaddr_in)。就是对应第三个参数的长度计算出来后存入一个变量后取地址

对于sendto()函数,成功则返回实际传送出去的字符数,失败返回-1,错误码被设置于errno 中。 

2.2recvfrom()

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                           struct sockaddr *src_addr, socklen_t *addrlen);

recvfrom()是从指定地址接收UDP数据报。 

\sockfd: socket描述符。

\buf: UDP数据报缓存地址。

\len: UDP数据报长度。

\flags: 该参数一般为0。

\dest_addr: sendto()函数参数,struct sockaddr类型,一般在使用时我们的类型是struct sockaddr_in类型,这时需要强制类型转换一下

\addrlen:addr(三种类型)长度,一般为:sizeof(struct sockaddr_in)。就是对应第三个参数的长度计算出来后存入一个变量后取地址

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+五条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值